zoukankan      html  css  js  c++  java
  • 【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、执行结果

     

  • 相关阅读:
    使用多线程生产者消费者模式实现抓斗图
    selenium+chrome抓取淘宝搜索抓娃娃关键页面
    mysql必知必会
    mongoDB高级查询$type4array使用解析
    并发服务器几种实现方法总结
    python的面向对象和面向过程
    lazarus,synedit输入小键盘特殊符号的补丁
    Delphi中静态方法重载还是覆盖的讨论
    python全栈开发_day4_if,while和for
    python全栈开发_day3_数据类型,输入输出及运算符
  • 原文地址:https://www.cnblogs.com/cuish/p/4136391.html
Copyright © 2011-2022 走看看