pthread_mutex.h頭文件
- #ifndef __SEM_UTIL_H__
- #define __SEM_UTIL_H__
- typedef void* SemHandl_t;
- SemHandl_t MakeSem(); ///< Initialize the semaphore.
- int SemRelease(SemHandl_t hndlSem); ///< Unlock the semaphore.
- int SemWait(SemHandl_t hndlSem); ///< Lock the semaphore.
- int DestroySem(SemHandl_t hndlSem); ///< Destory the semaphore.
- #endif
pthread_mutex.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)
- /*線程互斥鎖初始化*/
- SemHandl_t MakeSem()
- {
- SemHandl_t hndlSem = malloc(sizeof(pthread_mutex_t));
- if(hndlSem == NULL){
- ERR("Not enough memory!!\n");
- return NULL;
- }
- /* Initialize the mutex which protects the global data */
- if(pthread_mutex_init(hndlSem, NULL) != 0){
- ERR("Sem init faill!!\n");
- free(hndlSem);
- return NULL;
- }
- return hndlSem;
- }
- /*線程互斥鎖釋放*/
- int SemRelease(SemHandl_t hndlSem)
- {
- if(hndlSem == NULL){
- ERR("SemRelease: Invalid Semaphore handler\n");
- return -1;
- }
- return pthread_mutex_unlock(hndlSem);
- }
- /*等待*/
- int SemWait(SemHandl_t hndlSem)
- {
- if(hndlSem == NULL){
- ERR("SemWait: Invalid Semaphore handler\n");
- return -1;
- }
- return pthread_mutex_lock(hndlSem);
- }
- /*刪除*/
- int DestroySem(SemHandl_t hndlSem)
- {
- if(hndlSem == NULL){
- ERR("DestroySem: Invalid Semaphore handler\n");
- return -1;
- }
- pthread_mutex_lock(hndlSem);
- pthread_mutex_unlock(hndlSem);
- if(pthread_mutex_destroy(hndlSem) !=0){
- ERR("Sem_kill faill!!\n");
- }
- free(hndlSem);
- return 0;
- }
有了以上基礎就可以再多線程中測試了,下面的代碼是在上篇文章的基礎上修改的
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;
- /*
- 某設備寫操作,不同同時訪問,所以所以需要線程鎖保護
- 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);
- DeviceWrite("thread 1");
- SemRelease(gHndlSem);
- 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);
- DeviceWrite("thread 2");
- 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;
- }
- if(XxManageThreadInit()==-1){
- exit(1);
- }
- while(count--){
- DBG("[0] main running\n");
- sleep(2);
- }
- SetXxThreadQuit();
- /*等待線程結束*/
- sleep(1);
- /*刪除線程鎖*/
- DestroySem(gHndlSem);
- DBG("waitting thread exit...\n");
- return 0;
- }
- #endif