條件變量同步鎖示例
此例根據上一篇文章修改 (見 http://www.linuxidc.com/Linux/2012-07/65030.htm )
請包含上一篇中的兩個文件(未做任何改動)
1/ pthread_mutex.h
2/ pthread_mutex.c
上一篇的thread.c文件修改如下
- /*
- 多線程同步示例,條件變量同步鎖
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <pthread.h>
-
- #include "pthread_mutex.h"
-
- #define __DEBUG
- #ifdef __DEBUG
- #define DBG(fmt,args...) fprintf(stdout, fmt, ##args)
- #else
- #define DBG(fmt,args...)
- #endif
- #define ERR(fmt,args...) fprintf(stderr, fmt, ##args)
-
- static int isThreadQuit = 0;
- SemHandl_t gHndlSem = NULL;
- /*條件變量同步鎖*/
- pthread_cond_t gNoneZero;
- unsigned int gCount = 0;//條件變量
- /*
- 某設備寫操作,不同同時訪問,所以所以需要線程鎖保護
- 1、將函數DeviceWrite中加鎖
- 2、在訪問DeviceWrite的線程中加鎖
- 以上兩種方法跟據需要選擇其一。
- 本例中在訪問的線程中加鎖
- */
- void DeviceWrite(char *str)
- {
- /*SemWait(gHndlSem);*/
- DBG("Device Write: %s\n",str);
- /*SemRelease(gHndlSem);*/
- }
- void SetXxThreadQuit()
- {
- /*quit*/
- isThreadQuit = 1;
- }
- void *XxManageThread(void *arg)
- {
- char *cmd = (char*)arg;
- DBG("arg value=%s\n",cmd);
- while(isThreadQuit==0){
-
- SemWait(gHndlSem);// 1、先鎖定
- while(gCount==0){// 2、判斷條件變量
- pthread_cond_wait(&gNoneZero,gHndlSem);// 3、如果滿足,等待
- }
- gCount = gCount-1;// 4、條件變量做相應調整
- DBG("gCount=%d\n",gCount);
- SemRelease(gHndlSem); // 5、開鎖
-
- sleep(1);
-
- }
- /*arg是將指針帶進來,cmd則相反,或者設置 NULL*/
- pthread_exit(cmd);
- //pthread_exit(NULL);
- }
- void *XxManageThreadMutex(void *arg)
- {
- char *cmd = (char*)arg;
- DBG("arg value=%s\n",cmd);
- while(isThreadQuit==0){
-
- SemWait(gHndlSem);
- if(gCount == 0){
- pthread_cond_signal(&gNoneZero);
- }
- gCount = gCount+1;
- DBG("gCount=%d\n",gCount);
- SemRelease(gHndlSem);
-
- sleep(1);
-
- }
- /*arg是將指針帶進來,cmd則相反,或者設置 NULL*/
- pthread_exit(cmd);
- //pthread_exit(NULL);
- }
-
- int XxManageThreadInit()
- {
- pthread_t tManageThread;
- pthread_t tManageThreadMutex;
-
- char *any="any value";
- char *retn;
- int ret;
- /*
- 第二個參數是設置線程屬性,一般很少用到(設置優先級等),第四個參數為傳遞到線程的指針,
- 可以為任何類型
- */
- ret = pthread_create(&tManageThread,NULL,XxManageThread,"1 thread");
- if(ret == -1){
- /*成功返回0.失敗返回-1*/
- ERR("Ctreate Thread ERROR\n");
- return -1;
- }
-
- ret = pthread_create(&tManageThreadMutex,NULL,XxManageThreadMutex,"2 thread");
- if(ret == -1){
- /*成功返回0.失敗返回-1*/
- ERR("Ctreate Thread ERROR\n");
- return -1;
- }
-
- /*
- 設置線程退出時資源的清理方式,如果是detach,退出時會自動清理
- 如果是join,則要等待pthread_join調用時才會清理
- */
- pthread_detach(tManageThread);
- pthread_detach(tManageThreadMutex);
- //pthread_join(tManageThread,retn);
- //DBG("retn value=%s\n",retn);
- return 0;
- }
-
- #define TEST_MAIN
- #ifdef TEST_MAIN
- int main()
- {
- printf("hello liuyu\n");
- int count=3;
- /*創建線程鎖*/
- gHndlSem = MakeSem();
- if(gHndlSem == NULL){
- return -1;
- }
- /*條件變量同步鎖初始化*/
- pthread_cond_init(&gNoneZero,NULL);
-
- if(XxManageThreadInit()==-1){
- exit(1);
- }
-
- while(count--){
- DBG("[0] main running\n");
- sleep(2);
- }
-
- SetXxThreadQuit();
- /*等待線程結束*/
- sleep(1);
- /*刪除條件變量同步鎖*/
- pthread_cond_destroy(&gNoneZero);
- /*刪除線程鎖*/
- DestroySem(gHndlSem);
- DBG("waitting thread exit...\n");
- return 0;
- }
- #endif