#include#include #include // 全局变量,所有的线程都共享这一份资源。 int tickets = 100; void * sellticket(void * arg) { // 卖票 while(tickets > 0) { usleep(6000); printf("%ld 正在卖第 %d 张门票n", pthread_self(), tickets); tickets--; } return NULL; } int main() { // 创建3个子线程 pthread_t tid1, tid2, tid3; pthread_create(&tid1, NULL, sellticket, NULL); pthread_create(&tid2, NULL, sellticket, NULL); pthread_create(&tid3, NULL, sellticket, NULL); // 回收子线程的资源,阻塞 pthread_join(tid1, NULL); pthread_join(tid2, NULL); pthread_join(tid3, NULL); // 设置线程分离。 // pthread_detach(tid1); // pthread_detach(tid2); // pthread_detach(tid3); pthread_exit(NULL); // 退出主线程 return 0; }
上面这个代码是有问题的他对于共享资源的代码片段没有进行保护
解决方法1:互斥量
#include#include #include // 全局变量,所有的线程都共享这一份资源。 int tickets = 1000; // 创建一个互斥量 pthread_mutex_t mutex; void * sellticket(void * arg) { // 卖票 while(1) { // 加锁 pthread_mutex_lock(&mutex); if(tickets > 0) { usleep(60000); printf("%ld 正在卖第 %d 张门票n", pthread_self(), tickets); tickets--; }else { // 解锁 pthread_mutex_unlock(&mutex); break; } // 解锁 pthread_mutex_unlock(&mutex); } return NULL; } int main() { // 初始化互斥量 pthread_mutex_init(&mutex, NULL); // 创建3个子线程 pthread_t tid1, tid2, tid3; pthread_create(&tid1, NULL, sellticket, NULL); pthread_create(&tid2, NULL, sellticket, NULL); pthread_create(&tid3, NULL, sellticket, NULL); // 回收子线程的资源,阻塞 pthread_join(tid1, NULL); pthread_join(tid2, NULL); pthread_join(tid3, NULL); pthread_exit(NULL); // 退出主线程 // 释放互斥量资源 pthread_mutex_destroy(&mutex); return 0; }
互斥量可能会产生死锁的问题
死锁例子1
//重复加锁 #include#include #include // 全局变量,所有的线程都共享这一份资源。 int tickets = 1000; // 创建一个互斥量 pthread_mutex_t mutex; void * sellticket(void * arg) { // 卖票 while(1) { // 加锁 重复加锁造成死锁 pthread_mutex_lock(&mutex); pthread_mutex_lock(&mutex); if(tickets > 0) { usleep(60000); printf("%ld 正在卖第 %d 张门票n", pthread_self(), tickets); tickets--; }else { // 解锁 pthread_mutex_unlock(&mutex); break; } // 解锁 pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex); } return NULL; } int main() { // 初始化互斥量 pthread_mutex_init(&mutex,NULL); // 创建3个子线程 pthread_t tid1, tid2, tid3; pthread_create(&tid1, NULL, sellticket, NULL); pthread_create(&tid2, NULL, sellticket, NULL); pthread_create(&tid3, NULL, sellticket, NULL); // 回收子线程的资源,阻塞 pthread_join(tid1, NULL); pthread_join(tid2, NULL); pthread_join(tid3, NULL); pthread_exit(NULL); // 退出主线程 // 释放互斥量资源 pthread_mutex_destroy(&mutex); return 0; }
死锁例子2
//多线程多锁抢占锁资源 #include#include #include //创建两个互斥量 pthread_mutex_t mutex1,mutex2; void * workA(void *arg){ pthread_mutex_lock(&mutex1); sleep(1); pthread_mutex_lock(&mutex2); printf("workA...n"); pthread_mutex_unlock(&mutex2); pthread_mutex_unlock(&mutex1); return NULL; } void *workB(void *arg){ pthread_mutex_lock(&mutex2); sleep(1); pthread_mutex_lock(&mutex1); printf("workB...n"); pthread_mutex_unlock(&mutex1); pthread_mutex_unlock(&mutex2); return NULL; } int main() { //创建两个子线程 pthread_t tid1,tid2; pthread_create(&tid1,NULL,workA,NULL); pthread_create(&tid2,NULL,workB,NULL); //回收子线程资源 pthread_join(tid1,NULL); pthread_join(tid2,NULL); //释放互斥量资源 pthread_mutex_destroy(&mutex1); pthread_mutex_destroy(&mutex2); return 0; }
对于读操作比写操作要多很多的场景可以用读写锁来提高效率
#include#include #include int num=1; pthread_rwlock_t rwlock; void *writeNum(void *arg){ while(1){ pthread_rwlock_wrlock(&rwlock); num++; printf("++write,tid:%ld,num:%dn",pthread_self(),num); pthread_rwlock_unlock(&rwlock); usleep(100); } return NULL; } void *readNum(void *arg){ while(1){ pthread_rwlock_rdlock(&rwlock); printf("===read,tid%ld,num:%dn",pthread_self(),num); pthread_rwlock_unlock(&rwlock); usleep(100); } return NULL; } int main() { pthread_rwlock_init(&rwlock,NULL); //创建3个写线程,5个读线程 pthread_t wtids[3],rtids[5]; for(int i=0;i<3;i++){ pthread_create(&wtids[i],NULL,writeNum,NULL); } for(int i=0;i<5;i++){ pthread_create(&rtids[i],NULL,readNum,NULL); } //设置线程分离 for(int i=0;i<3;i++){ pthread_detach(wtids[i]); } for(int i=0;i<5;i++){ pthread_detach(rtids[i]); } pthread_exit(NULL); pthread_rwlock_destroy(&rwlock); return 0; }



