首页 > 代码库 > 【Linux】Mutex互斥量线程同步的例子

【Linux】Mutex互斥量线程同步的例子

 

0、互斥量

 

 Windows下的互斥量

 

是个内核对象,每次WaitForSingleObject和ReleaseMutex时都会检查当前线程ID和占有互斥量的线程ID是否一致。

当多次Wait**时就要对应多次ReleaseMutex, 当ReleaseMutex过多次数时如果发现当前占有互斥量的线程ID和当前调用ReleaseMutex的线程ID不一致时仅仅返回FLASE,GetLastError返回ERROR_NOT_OWNER,没有其他副作用。

 

当占有mutex的线程在Release之前退出时,该mutex被【遗弃】,此时系统自动收回mutex,可供其他线程申请。

 

允许多次等待

WaitForSingleObject(hMutex, time);

WaitForSingleObject(hMutex, itme);

 

多次等待 对应多次释放

ReleaseMutex(hMutex);

ReleaseMutex(hMutex);

 

 

Linux下的互斥量

可以设置互斥量的属性是否为可以被同一个线程多次lock,  还可以设置该互斥量的范围,即是用于进程之间同步 还是 同一进程不同线程之间的同步。

相关API 将说明见代码注释部分。

 

 

 

1、相关API

 

//Initialize a mutex with attribute(can be NULL)                                                                        int pthread_mutex_init(                                                                                                    pthread_mutex_t* mutex,                                                                                               const pthread_mutexattr_t* mutexattr);                                                                                                                                                                                                 //lock a mutex                                                                                                          int pthread_mutex_lock(pthread_mutex_t* mutex);                                                                                                                                                                                             //ulock a mutex                                                                                                        int pthread_mutex_unlock(pthread_mutex_t* mutex);                                                                                                                                                                                           //destroy a mutex                                                                                                       int pthread_mutex_destroy(pthread_mutex_t* mutex);                                                                                                                                                                                          int pthread_mutexattr_setpshared(                                                                                           pthread_mutexattr_t* mattr,                                                                                           int pshared  //PTHREAD_PROCESS_SHARE | PTHREAD_PROCESS_PRIVATE                                                        );                                                                                                                                                                                                                                    int pthread_mutexattr_getshared(                                                                                      pthread_mutexattr_t* mattr,                                                                                           int* pshared);                                                                                                                                                                                                                              int pthread_mutexattr_settype(                                                                                             pthread_mutexattr_t* attr,                                                                                           int type  //PTHREAD_MUTEX_TIMED_NP -- default value                                                                            //PTHREAD_MUTEX_RECURISIVE_NP -- allow a thread lock multitimes                                                      //PTHREAD_MUTEX_ERRORCHECK_NO -- check error lock, return EDEADLK if the same thread want to LOCK                    //PTHREAD_MUTEX_ADAPTIVE_NO -- adaptive lock, the simplest lock                                       )                                                                                                                                                                                                                                                                                                                                                                 int pthread_mutexattr_gettype(                                                                                             pthread_mutexattr_t* attr,                                                                                           int* type                                                                                                       )                                                                                                                     

 

 

 

 

2、demo

 

#include <iostream>#include <pthread.h>#include <unistd.h>#include <errno.h>using namespace std;/*********************************************** *  * Initialize a mutex with attribute(can be NULL) * int pthread_mutex_init( *      pthread_mutex_t* mutex,  *      const pthread_mutexattr_t* mutexattr); *  * lock a mutex * int pthread_mutex_lock(pthread_mutex_t* mutex); * * unlock a mutex * int pthread_mutex_unlock(pthread_mutex_t* mutex); * * destroy a mutex * int pthread_mutex_destroy(pthread_mutex_t* mutex); * * int pthread_mutexattr_setpshared( *       pthread_mutexattr_t* mattr, *       int pshared  //PTHREAD_PROCESS_SHARE | PTHREAD_PROCESS_PRIVATE *       ); *  * int pthread_mutexattr_getshared( * pthread_mutexattr_t* mattr, * int* pshared); * * int pthread_mutexattr_settype( *         pthread_mutexattr_t* attr, *         int type  //PTHREAD_MUTEX_TIMED_NP -- default value *                   //PTHREAD_MUTEX_RECURISIVE_NP -- allow a thread lock multitimes *                   //PTHREAD_MUTEX_ERRORCHECK_NO -- check error lock, return EDEADLK if the same thread want to LOCK *                   //PTHREAD_MUTEX_ADAPTIVE_NO -- adaptive lock, the simplest lock * ) * * * int pthread_mutexattr_gettype( *         pthread_mutexattr_t* attr, *         int* type * ) * *********************************************/void* work_thread(void* p){    if (NULL == p)        return  const_cast<char*>("invalid thread argument");    pthread_mutex_t* pMutex = (pthread_mutex_t*)(p);    //current thread ID    pthread_t nThreadID = pthread_self();    int i = 0;    while(++ i <= 3)    {        //lock multi times         pthread_mutex_lock(pMutex);        pthread_mutex_lock(pMutex);                cout << "Thread " << nThreadID << " is Running! " << endl;                //and so unlock multi times        pthread_mutex_unlock(pMutex);        pthread_mutex_unlock(pMutex);        usleep(1000 * 1); //1 miliseconds    }            return const_cast<char*>("------ finish -----------");}void* work_thread2(void* p){    if (NULL == p)        return  const_cast<char*>("invalid thread argument");    pthread_mutex_t* pMutex = (pthread_mutex_t*)(p);        //current thread ID    pthread_t nThreadID = pthread_self();    int i = 0;    while(++ i <= 3)    {        //if current thread can not enter mutex,         //and the function pthread_mutex_trylock will RETURN Immediatly        if ( EBUSY == pthread_mutex_trylock(pMutex))            cout << "Other thread is lock the resouce, i am waiting.." << endl;        else        {            cout << "Thread " << nThreadID << " is Running! " << endl;                pthread_mutex_unlock(pMutex);            usleep(1000 * 1); //1 miliseconds        }    }            return const_cast<char*>("------ finish -----------");}int main(){    const size_t nThreadCount = 3;    pthread_t threadIDs[nThreadCount];    int nRet = -1;    pthread_mutex_t mutex;    pthread_mutexattr_t mutexattr;    void* pRet = NULL; //thread return value    //allow a thread lock multi times    nRet = pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE_NP);        nRet = pthread_mutex_init(&mutex, &mutexattr);    if (0 != nRet)        return -1;    for (size_t i = 0; i < nThreadCount - 1; ++ i)    {        nRet = pthread_create(&threadIDs[i], NULL, work_thread, (void*)(&mutex));        if (0 != nRet)            continue;    }        nRet = pthread_create(&threadIDs[nThreadCount - 1], NULL, work_thread2, (void*)(&mutex));    if (0 != nRet)        cerr << endl << "work_thread2 created falied! " << endl;    for (size_t i = 0; i < nThreadCount; ++ i)    {        nRet = pthread_join(threadIDs[i], &pRet);        if (0 == nRet)        {            cout << " Thread " << threadIDs[i] << " Finished ! "                 " It‘s return value is " << (char*)pRet << endl;        }    }    pthread_mutex_destroy(&mutex);    return 0;}

 

 

 

 

 

3、执行结果

 

 

 

 

 

【Linux】Mutex互斥量线程同步的例子