c - C 中的线程安全

标签 c multithreading thread-safety

假设我用 C 语言编写了一个库。此外,假设要在多线程环境中使用该库。 如何使其成为线程安全的?更具体地说:我如何确保某些功能一次仅由一个线程执行?

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

最佳答案

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

我将以 Windows 和 Linux 为例展示我是如何做到的。它是用 C++ 而不是 C,但它只是一个例子:

#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 - C 中的线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2029605/

相关文章:

c++ - 在另一个线程中绘制 OpenGL

C++ Boost 线程。如何使用递归尝试锁?死锁发生在并发代码中

python - Python 解包线程安全吗?

C++ STL map/vector of vectors 和线程安全

java - 有没有办法让 Java 线程只在初始化时执行某些操作?

C 空字符导致程序行为出现问题

c - glibc什么时候会发生文件流锁定?

c++ - winsock 总是在套接字上返回 -1

c - 刽子手游戏的简化(且不完整)版本中的错误

java - 如何让构造函数安全?