C 中的线程安全 [英] Thread Safety in C

查看:66
本文介绍了C 中的线程安全的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想象一下我用 C 编写了一个库.此外,想象一下这个库在多线程环境中使用.如何使其成为线程安全的?更具体的:我如何确保某些功能一次仅由一个线程执行?

imagine I write a library in C. Further, imagine this library to be used from a multi-threaded environment. How do I make it thread-safe? More specific: How do I assure, that certain functions are executed only by one thread at a time?

与Java或C#相反,C没有办法处理线程/锁/等,C标准库也没有.我知道,操作系统支持线程,但是使用它们的 api 会极大地限制我的库的兼容性.我有哪些可能性可以使我的库尽可能兼容/便携?(例如,依赖 OpenMP 或 Posix 线程以使其与至少所有类 Unix 操作系统兼容?)

In opposite to Java or C# for example, C has no means to deal with threads/locks/etc., nor does the C standard library. I know, that operating systems support threads, but using their api would restrict the compatibility of my library very much. Which possibilities do I have, to keep my library as compatible/portable as possible? (for example relying on OpenMP, or on Posix threads to keep it compatible with at least all unix-like operating systems?)

推荐答案

您可以使用 #ifdef 创建包装器.这真的是你能做的最好的.(或者您可以使用第三方库来执行此操作).

You can create wrappers with #ifdef. It's really the best you can do. (Or you can use a third party library to do this).

作为 windows 和 linux 的示例,我将展示我是如何做到的.它是在 C++ 中而不是在 C 中,但它只是一个例子:

I'll show how I did it as an example for windows and linux. It's in C++ and not C but again it's just an example:

#ifdef WIN32
typedef HANDLE thread_t;
typedef unsigned ThreadEntryFunction;
#define thread __declspec(thread)

class Mutex : NoCopyAssign
{
public:
    Mutex() { InitializeCriticalSection(&mActual); }
    ~Mutex() { DeleteCriticalSection(&mActual); }
    void Lock() { EnterCriticalSection(&mActual); }
    void Unlock() { LeaveCriticalSection(&mActual); }
private:
    CRITICAL_SECTION mActual;
};

class ThreadEvent : NoCopyAssign
{
public:
    ThreadEvent() { Actual = CreateEvent(NULL, false, false, NULL); }
    ~ThreadEvent() { CloseHandle(Actual); }
    void Send() { SetEvent(Actual); }

    HANDLE Actual;
};
#else
typedef pthread_t thread_t;
typedef void *ThreadEntryFunction;
#define thread __thread
extern pthread_mutexattr_t MutexAttributeRecursive;

class Mutex : NoCopyAssign
{
public:
    Mutex() { pthread_mutex_init(&mActual, &MutexAttributeRecursive); }
    ~Mutex() { pthread_mutex_destroy(&mActual); }
    void Lock() { pthread_mutex_lock(&mActual); }
    void Unlock() { pthread_mutex_unlock(&mActual); }
private:
    pthread_mutex_t mActual;
};

class ThreadEvent : NoCopyAssign
{
public:
    ThreadEvent() { pthread_cond_init(&mActual, NULL); }
    ~ThreadEvent() { pthread_cond_destroy(&mActual); }

    void Send() { pthread_cond_signal(&mActual); }
private:
    pthread_cond_t mActual;
};

inline thread_t GetCurrentThread() { return pthread_self(); }
#endif

/* Allows for easy mutex locking */
class MutexLock : NoAssign
{
public:
    MutexLock(Mutex &m) : mMutex(m) { mMutex.Lock(); }
    ~MutexLock() { mMutex.Unlock(); }
private:
    Mutex &mMutex;
};

这篇关于C 中的线程安全的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆