linux基礎編程 多線程中的互斥鎖 pthread_mutex_lock

pthread_mutex.h頭文件

  1. #ifndef __SEM_UTIL_H__  
  2. #define __SEM_UTIL_H__  
  3.   
  4. typedef void* SemHandl_t;  
  5.   
  6. SemHandl_t MakeSem(); ///< Initialize the semaphore.  
  7. int SemRelease(SemHandl_t hndlSem); ///< Unlock the semaphore.  
  8. int SemWait(SemHandl_t hndlSem); ///< Lock the semaphore.  
  9. int DestroySem(SemHandl_t hndlSem); ///< Destory the semaphore.  
  10.   
  11.   
  12. #endif  

pthread_mutex.c源文件

  1. /* 
  2. 互斥鎖用來保證一段時間內只有一個線程在執行一段代碼。 
  3. 必要性顯而易見:假設各個線程向同一個文件順序寫入數據, 
  4. 最後得到的結果一定是災難性的。 
  5. */  
  6. #include <stdio.h>  
  7. #include <stdlib.h>  
  8. #include <unistd.h>  
  9. #include <pthread.h>  
  10.   
  11. #include "pthread_mutex.h"  
  12.   
  13. #define __DEBUG  
  14. #ifdef __DEBUG  
  15. #define DBG(fmt,args...) fprintf(stdout,  fmt,  ##args)  
  16. #else  
  17. #define DBG(fmt,args...)  
  18. #endif  
  19. #define ERR(fmt,args...) fprintf(stderr,  fmt,  ##args)  
  20.   
  21. /*線程互斥鎖初始化*/  
  22. SemHandl_t MakeSem()  
  23. {  
  24.     SemHandl_t hndlSem = malloc(sizeof(pthread_mutex_t));  
  25.     if(hndlSem == NULL){  
  26.         ERR("Not enough memory!!\n");  
  27.         return NULL;  
  28.     }  
  29.     /* Initialize the mutex which protects the global data */  
  30.     if(pthread_mutex_init(hndlSem, NULL) != 0){  
  31.         ERR("Sem init faill!!\n");  
  32.         free(hndlSem);  
  33.         return NULL;  
  34.     }  
  35.     return hndlSem;  
  36. }  
  37.   
  38. /*線程互斥鎖釋放*/  
  39. int SemRelease(SemHandl_t hndlSem)  
  40. {  
  41.     if(hndlSem == NULL){  
  42.         ERR("SemRelease: Invalid Semaphore handler\n");  
  43.         return -1;  
  44.     }  
  45.     return pthread_mutex_unlock(hndlSem);  
  46. }  
  47.   
  48. /*等待*/  
  49. int SemWait(SemHandl_t hndlSem)  
  50. {  
  51.     if(hndlSem == NULL){  
  52.         ERR("SemWait: Invalid Semaphore handler\n");  
  53.         return -1;  
  54.     }  
  55.     return pthread_mutex_lock(hndlSem);  
  56. }  
  57.   
  58. /*刪除*/  
  59. int DestroySem(SemHandl_t hndlSem)  
  60. {  
  61.     if(hndlSem == NULL){  
  62.         ERR("DestroySem: Invalid Semaphore handler\n");  
  63.         return -1;  
  64.     }  
  65.     pthread_mutex_lock(hndlSem);  
  66.     pthread_mutex_unlock(hndlSem);  
  67.     if(pthread_mutex_destroy(hndlSem) !=0){  
  68.         ERR("Sem_kill faill!!\n");  
  69.     }  
  70.     free(hndlSem);  
  71.     return 0;  
  72. }  

有了以上基礎就可以再多線程中測試了,下面的代碼是在上篇文章的基礎上修改的

thread.c 源文件

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <unistd.h>  
  4. #include <pthread.h>  
  5.   
  6. #include "pthread_mutex.h"  
  7.   
  8. #define __DEBUG  
  9. #ifdef __DEBUG  
  10. #define DBG(fmt,args...) fprintf(stdout,  fmt,  ##args)  
  11. #else  
  12. #define DBG(fmt,args...)  
  13. #endif  
  14. #define ERR(fmt,args...) fprintf(stderr,  fmt,  ##args)  
  15.   
  16. static int isThreadQuit = 0;  
  17. SemHandl_t gHndlSem = NULL;  
  18.   
  19. /* 
  20. 某設備寫操作,不同同時訪問,所以所以需要線程鎖保護 
  21. 1、將函數DeviceWrite中加鎖 
  22. 2、在訪問DeviceWrite的線程中加鎖 
  23. 以上兩種方法跟據需要選擇其一。 
  24. 本例中在訪問的線程中加鎖 
  25. */  
  26. void DeviceWrite(char *str)  
  27. {  
  28.     /*SemWait(gHndlSem);*/  
  29.     DBG("Device Write: %s\n",str);  
  30.     /*SemRelease(gHndlSem);*/  
  31. }  
  32. void SetXxThreadQuit()  
  33. {     
  34.     /*quit*/  
  35.     isThreadQuit = 1;  
  36. }  
  37. void *XxManageThread(void *arg)  
  38. {  
  39.     char *cmd = (char*)arg;  
  40.     DBG("arg value=%s\n",cmd);  
  41.     while(isThreadQuit==0){  
  42.         SemWait(gHndlSem);  
  43.         DeviceWrite("thread 1");  
  44.         SemRelease(gHndlSem);  
  45.         sleep(1);  
  46.     }  
  47.     /*arg是將指針帶進來,cmd則相反,或者設置 NULL*/  
  48.     pthread_exit(cmd);  
  49.     //pthread_exit(NULL);  
  50. }  
  51. void *XxManageThreadMutex(void *arg)  
  52. {  
  53.     char *cmd = (char*)arg;  
  54.     DBG("arg value=%s\n",cmd);  
  55.     while(isThreadQuit==0){  
  56.         SemWait(gHndlSem);  
  57.         DeviceWrite("thread 2");  
  58.         SemRelease(gHndlSem);  
  59.         sleep(1);  
  60.     }  
  61.     /*arg是將指針帶進來,cmd則相反,或者設置 NULL*/  
  62.     pthread_exit(cmd);  
  63.     //pthread_exit(NULL);  
  64. }  
  65.   
  66. int XxManageThreadInit()  
  67. {  
  68.     pthread_t tManageThread;  
  69.     pthread_t tManageThreadMutex;  
  70.       
  71.     char *any="any value";  
  72.     char *retn;  
  73.     int ret;  
  74.     /* 
  75.       第二個參數是設置線程屬性,一般很少用到(設置優先級等),第四個參數爲傳遞到線程的指針, 
  76.       可以爲任何類型 
  77.     */  
  78.     ret = pthread_create(&tManageThread,NULL,XxManageThread,"1 thread");  
  79.     if(ret == -1){  
  80.         /*成功返回0.失敗返回-1*/  
  81.         ERR("Ctreate Thread ERROR\n");  
  82.         return -1;  
  83.     }  
  84.   
  85.     ret = pthread_create(&tManageThreadMutex,NULL,XxManageThreadMutex,"2 thread");  
  86.     if(ret == -1){  
  87.         /*成功返回0.失敗返回-1*/  
  88.         ERR("Ctreate Thread ERROR\n");  
  89.         return -1;  
  90.     }  
  91.       
  92.     /* 
  93.       設置線程退出時資源的清理方式,如果是detach,退出時會自動清理 
  94.       如果是join,則要等待pthread_join調用時纔會清理 
  95.     */  
  96.     pthread_detach(tManageThread);  
  97.     pthread_detach(tManageThreadMutex);  
  98.     //pthread_join(tManageThread,retn);  
  99.     //DBG("retn value=%s\n",retn);  
  100.     return 0;  
  101. }  
  102.   
  103. #define TEST_MAIN  
  104. #ifdef TEST_MAIN  
  105. int main()  
  106. {  
  107.     printf("hello liuyu\n");  
  108.     int count=3;  
  109.     /*創建線程鎖*/  
  110.     gHndlSem = MakeSem();  
  111.     if(gHndlSem == NULL){  
  112.         return -1;  
  113.     }  
  114.       
  115.     if(XxManageThreadInit()==-1){  
  116.         exit(1);  
  117.     }  
  118.       
  119.     while(count--){  
  120.         DBG("[0] main running\n");  
  121.         sleep(2);  
  122.     }  
  123.       
  124.     SetXxThreadQuit();  
  125.     /*等待線程結束*/  
  126.     sleep(1);  
  127.     /*刪除線程鎖*/  
  128.     DestroySem(gHndlSem);  
  129.     DBG("waitting thread exit...\n");  
  130.     return 0;  
  131. }  
  132. #endif  
發佈了62 篇原創文章 · 獲贊 6 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章