Unix 环境高级编程---线程创建、同步、
一下代码主要实现了linux下线程创建的基本方法,这些都是使用默认属性的。以后有机会再探讨自定义属性的情况。主要是为了练习三种基本的线程同步方法:互斥、读写锁以及条件变量。
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <string.h> int g_count = 0; pthread_mutex_t mutex_lock; pthread_rwlock_t rw_lock; pthread_cond_t con_val = PTHREAD_COND_INITIALIZER; typedef enum { MutexLock = 0, RWLock, CondLock }LockType; typedef struct { int val; LockType type; }ThreadData; void PrintThreadId() { pid_t pid; pthread_t tid; pid = getpid(); tid = pthread_self(); printf("[%s] process id : %d thread id : 0x%lx\n",__func__,pid,tid); } void CleanUpFun(void *arg) { printf("[%s] clean up : %s \n",__func__,(char *)arg); } void AddCount(int tid,LockType type) { if(type == MutexLock) { printf("[%s] thread %d MutexLock the count is : %d\n",__func__,tid,g_count); pthread_mutex_lock(&mutex_lock); while(g_count < 10) { usleep(1); printf("%d-%d \t",tid,g_count); g_count++; } printf("\n"); pthread_mutex_unlock(&mutex_lock); } if(type == RWLock) { pthread_rwlock_wrlock(&rw_lock); printf("[%s] thread %d RWLock the count is : %d\n",__func__,tid,g_count); while(g_count < 10) { usleep(1); printf("%d-%d \t",tid,g_count); g_count++; } printf("\n"); pthread_rwlock_unlock(&rw_lock); } if(type == CondLock) { printf("[%s] thread %d CondLock the count is : %d\n",__func__,tid,g_count); pthread_mutex_lock(&mutex_lock); g_count = 1217; printf("[%s] thread %d CondLock the count is : %d\n",__func__,tid,g_count); pthread_mutex_unlock(&mutex_lock); pthread_cond_signal(&con_val); } } void DelCount(int tid,LockType type) { usleep(1); if(type == MutexLock) { pthread_mutex_lock(&mutex_lock); printf("[%s] thread %d MutexLock the count is : %d\n",__func__,tid,g_count); while(g_count > 0) { usleep(1); printf("%d-%d \t",tid,g_count); g_count--; } printf("\n"); pthread_mutex_unlock(&mutex_lock); } if(type == RWLock) { pthread_rwlock_wrlock(&rw_lock); printf("[%s] thread %d RWLock the count is : %d\n",__func__,tid,g_count); while(g_count > 0) { usleep(1); printf("%d-%d \t",tid,g_count); g_count--; } printf("\n"); pthread_rwlock_unlock(&rw_lock); } if(type == CondLock) { pthread_mutex_lock(&mutex_lock); // printf("[%s] thread %d CondLock the count is : %d\n",__func__,tid,g_count); //while(1) { pthread_cond_wait(&con_val,&mutex_lock); printf("[%s] thread %d CondLock the count is : %d\n",__func__,tid,g_count); } pthread_mutex_unlock(&mutex_lock); } } void PrintCount(int tid,LockType type) { if(type == RWLock) { pthread_rwlock_rdlock(&rw_lock); printf("[%s] thread %d RWLock the count is : %d\n",__func__,tid,g_count); pthread_rwlock_unlock(&rw_lock); } else { } } void ChangCount(int tid,LockType type) { if((tid == 2) || (tid == 4)) { AddCount(tid,type); } else if((tid == 1)) { DelCount(tid,type); } else if(tid == 3) { PrintCount(tid,type); } } void * ThreadFun(ThreadData *t) { printf("\n----------------------------------------------------------\n"); int val = 0; LockType type = 0; val = t->val; type = t->type; printf("[%s] this is thread %d\n",__func__,val); PrintThreadId(); char buf[1024]; sprintf(buf,"thread %d first handler ",val); pthread_cleanup_push(CleanUpFun,buf);/*push and pop must be coupled*/ int len = strlen(buf); sprintf(buf+len+1,"thread %d second handler ",val);/*Notice !!! */ pthread_cleanup_push(CleanUpFun,buf+len+1);/*the buf must start from different address , to the cleanupfunc ,the poniter is the same !!!*/ ChangCount(val,type); if(val == 1) { printf("----------------------------------------------------------\n"); return ((void *)val);/*clean up func won't run*/ } else { printf("----------------------------------------------------------\n"); pthread_exit((void *)val);/*clean up func won run*/ } pthread_cleanup_pop(0); pthread_cleanup_pop(0); return ((void *)val); } void JoinThread(pthread_t tid) { void * ret; int err; err = pthread_join(tid,&ret); if(err != 0) { printf("error to join thread %lu\n",tid); } printf("\n[%s] catch thread 0x%lx , the return val is %d\n",__func__,tid,(int)ret); } void CreateThread(LockType type) { int err; ThreadData t1; ThreadData t2; ThreadData t3; t1.val = 1; t2.val = 2; t3.val = 3; pthread_t tid_1; pthread_t tid_2; pthread_t tid_3; if(type == MutexLock) { /*Mutex lock*/ t1.type = MutexLock; t2.type = MutexLock; t3.type = MutexLock; err = pthread_create(&tid_1,NULL,(void *)ThreadFun,(void *)&t1); if(err != 0) { printf("error to create thread !\n"); } err = pthread_create(&tid_2,NULL,(void *)ThreadFun,(void *)&t2); if(err != 0) { printf("error to create thread !\n"); } JoinThread(tid_1); JoinThread(tid_2); } else if(type == RWLock) { /*rw lock*/ t1.type = RWLock; t2.type = RWLock; t3.type = RWLock; err = pthread_create(&tid_1,NULL,(void *)ThreadFun,(void *)&t1); if(err != 0) { printf("error to create thread !\n"); } err = pthread_create(&tid_2,NULL,(void *)ThreadFun,(void *)&t2); if(err != 0) { printf("error to create thread !\n"); } err = pthread_create(&tid_3,NULL,(void *)ThreadFun,(void *)&t3); if(err != 0) { printf("error to create thread !\n"); } JoinThread(tid_1); JoinThread(tid_2); JoinThread(tid_3); } else if(type == CondLock) { t1.type = CondLock; err = pthread_create(&tid_1,NULL,(void *)ThreadFun,(void *)&t1); if(err != 0) { printf("error to create thread !\n"); } sleep(1); t2.type = CondLock; err = pthread_create(&tid_2,NULL,(void *)ThreadFun,(void *)&t2); if(err != 0) { printf("error to create thread !\n"); } JoinThread(tid_1); JoinThread(tid_2); } } void InitMutexLock() { if(pthread_mutex_init(&mutex_lock,NULL) != 0) { printf("[Main] error to init mutex lock\n"); } } void DestoryMutexLock() { if(pthread_mutex_destroy(&mutex_lock) != 0) { printf("[Main] error to destory mutex lock\n"); } } void DestoryRWLock() { if(pthread_rwlock_destroy(&rw_lock) != 0) { printf("[Main] error to destroy rw lock \n"); } } void InitRWLock() { if(pthread_rwlock_init(&rw_lock,NULL) != 0) { printf("[Main] error to init rw lock\n"); } } int main(int argc,char **argv) { printf("=====================================mutex lock=====================================\n"); InitMutexLock(); CreateThread(MutexLock); DestoryMutexLock(); printf("=====================================rw lock=====================================\n"); InitRWLock(); CreateThread(RWLock); DestoryRWLock(); printf("=====================================Cond lock=====================================\n"); InitMutexLock(); CreateThread(CondLock); DestoryMutexLock(); printf("[Main] quit\n"); return 0; }
运行效果如下:
tiger@ubuntu:/mnt/hgfs/e/Lessons/MyExercise/UtilLibs/THREAD$ ./thread =====================================mutex lock===================================== ---------------------------------------------------------- [ThreadFun] this is thread 2 [PrintThreadId] process id : 10948 thread id : 0xb6f54b70 [AddCount] thread 2 MutexLock the count is : 0 ---------------------------------------------------------- [ThreadFun] this is thread 1 [PrintThreadId] process id : 10948 thread id : 0xb7755b70 2-0 2-1 2-2 2-3 2-4 2-5 2-6 2-7 2-8 2-9 ---------------------------------------------------------- [DelCount] thread 1 MutexLock the count is : 10 1-10 [CleanUpFun] clean up : thread 2 second handler [CleanUpFun] clean up : thread 2 first handler 1-9 1-8 1-7 1-6 1-5 1-4 1-3 1-2 1-1 ---------------------------------------------------------- [JoinThread] catch thread 0xb7755b70 , the return val is 1 [JoinThread] catch thread 0xb6f54b70 , the return val is 2 =====================================rw lock===================================== ---------------------------------------------------------- [ThreadFun] this is thread 3 [PrintThreadId] process id : 10948 thread id : 0xb6753b70 [PrintCount] thread 3 RWLock the count is : 0 ---------------------------------------------------------- [CleanUpFun] clean up : thread 3 second handler [CleanUpFun] clean up : thread 3 first handler ---------------------------------------------------------- [ThreadFun] this is thread 2 [PrintThreadId] process id : 10948 thread id : 0xb7755b70 [AddCount] thread 2 RWLock the count is : 0 ---------------------------------------------------------- [ThreadFun] this is thread 1 [PrintThreadId] process id : 10948 thread id : 0xb6f54b70 2-0 2-1 2-2 2-3 2-4 2-5 2-6 2-7 2-8 2-9 ---------------------------------------------------------- [CleanUpFun] clean up : thread 2 second handler [CleanUpFun] clean up : thread 2 first handler [DelCount] thread 1 RWLock the count is : 10 1-10 1-9 1-8 1-7 1-6 1-5 1-4 1-3 1-2 1-1 ---------------------------------------------------------- [JoinThread] catch thread 0xb6f54b70 , the return val is 1 [JoinThread] catch thread 0xb7755b70 , the return val is 2 [JoinThread] catch thread 0xb6753b70 , the return val is 3 =====================================Cond lock===================================== ---------------------------------------------------------- [ThreadFun] this is thread 1 [PrintThreadId] process id : 10948 thread id : 0xb6753b70 ---------------------------------------------------------- [ThreadFun] this is thread 2 [PrintThreadId] process id : 10948 thread id : 0xb7755b70 [AddCount] thread 2 CondLock the count is : 0 [AddCount] thread 2 CondLock the count is : 1217 [DelCount] thread 1 CondLock the count is : 1217 ---------------------------------------------------------- [JoinThread] catch thread 0xb6753b70 , the return val is 1 ---------------------------------------------------------- [CleanUpFun] clean up : thread 2 second handler [CleanUpFun] clean up : thread 2 first handler [JoinThread] catch thread 0xb7755b70 , the return val is 2 [Main] quit tiger@ubuntu:/mnt/hgfs/e/Lessons/MyExercise/UtilLibs/THREAD$
代码相当拙劣基础,欢迎拍砖。