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
/* 互斥锁用来保证一段时间内只有一个线程在执行一段代码。 必要性显而易见:假设各个线程向同一个文件顺序写入数据, 最后得到的结果一定是灾难性的。 */ #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