C中的螺纹安全性

Dav*_* O. 10 c multithreading thread-safety

想象一下我用C编写了一个库.进一步,想象一下这个库是从多线程环境中使用的.如何使其线程安全?更具体:我如何确保某些功能一次只能由一个线程执行?

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

Tho*_*ini 18

您可以使用#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;
};
Run Code Online (Sandbox Code Playgroud)

  • 他们这样做是出于各种原因,可能是因为他们没有被埋葬或者对他们的老板生气 - 不要担心我会尽力"修复"这种损害,因为他们没有给你任何关键的理由 (6认同)

R S*_*hko 5

您将需要使用操作系统的线程库.在Posix上,通常是pthreads,你会想要pthread_mutex_lock.

Windows拥有自己的线程库,您需要查看关键部分CreateMutex.关键部分更加优化,但仅限于单个进程,您不能在WaitForMultipleObjects中使用它们.