为了保证线程在执行某段代码时不被其他线程打断,可以使用互斥锁进行保护,而这段被保护的代码区域被称为临界区。
原理:线程执行锁定函数pthread_mutex_lock()时,如果锁没有被其他线程占用,则获取并占用锁,然后执行自己后面的代码段;此时其他线程无法获取锁,在执行到pthread_mutex_lock()时会休眠,直到占用锁的线程通过pthread_mutex_unlock()把锁释放,才有机会被唤醒并占有锁,然后执行后续代码。
1 //由于pthread库不是Linux系统默认的库,连接时需要使用库libpthread.a,所以在使用pthread_create创建线程时,在编译中要加-lpthread参数 2 //gcc pthread_mutex.c -lpthread -o pthread 3 #include <stdio.h> 4 #include <sched.h> 5 #include <pthread.h> 6 void *producter_f(void *arg); 7 void *consumer_f(void *arg); 8 int buffer_has_item = 0; 9 pthread_mutex_t mutex; 10 int running = 1; 11 12 int main(void) 13 { 14 pthread_t consumer_t; 15 pthread_t producter_t; 16 pthread_mutex_init(&mutex, NULL); 17 pthread_create(&producter_t, NULL, (void*)producter_f, NULL); 18 pthread_create(&consumer_t, NULL, (void*)consumer_f, NULL); 19 sleep(5); 20 running = 0; 21 pthread_join(consumer_t, NULL); 22 pthread_join(producter_t, NULL); 23 24 pthread_mutex_destroy(&mutex); 25 } 26 27 void *producter_f(void *arg) 28 { 29 while(running) 30 { 31 pthread_mutex_lock(&mutex); 32 printf("生产前,总数量:%d\n", buffer_has_item); 33 buffer_has_item++; 34 printf("生产后,总数量:%d\n", buffer_has_item); 35 pthread_mutex_unlock(&mutex); 36 sleep(1); 37 } 38 } 39 40 void *consumer_f(void *arg) 41 { 42 while(running) 43 { 44 pthread_mutex_lock(&mutex); 45 printf("消费前,总数量:%d\n", buffer_has_item); 46 buffer_has_item--; 47 printf("消费后,总数量:%d\n", buffer_has_item); 48 pthread_mutex_unlock(&mutex); 49 sleep(1); 50 } 51 }
这段代码输出:
生产前,总数量:0
生产后,总数量:1
消费前,总数量:1
消费后,总数量:0
或者输出:
消费前,总数量:0
消费后,总数量:-1
生产前,总数量:-1
生产后,总数量:0
生产前,总数量:0
生产后,总数量:1
输出结果可能有多种,是由于线程竞争锁的结果是不确定的。但无论哪种结果,临界区内的代码块总是能执行完成而不会被打断。
生产者临界区:
32 printf("生产前,总数量:%d\n", buffer_has_item); 33 buffer_has_item++; 34 printf("生产后,总数量:%d\n", buffer_has_item);
消费者临界区:
45 printf("消费前,总数量:%d\n", buffer_has_item); 46 buffer_has_item--; 47 printf("消费后,总数量:%d\n", buffer_has_item);标签:item,buffer,void,间通信,互斥,mutex,pthread,线程 From: https://www.cnblogs.com/zzx2bky/p/17003441.html