Linux 的线程同步机制主要有信号量、互斥量、读写互斥和条件变量等。
信号量
线程信号量实际上是一个非负的整数计数器,用来实现对公共资源的控制。
头文件: #include <semaphore.h>
互斥锁
互斥锁是用来保护临界区的,保证在某时间段内只有一个线程在访问某一资源。
条件变量
条件变量是一种同步机制,允许线程挂起,直到共享资源上的某些条件得到满足,与线程锁配合使用。
相关函数:
pthread_cond_t test_th_cond = PTHREAD_COND_INITIALIZER; //申请变量(静态初始化) int pthread_cond_init(pthread_cond_t *restrict,const pthread_condattr_t *restrict); //初始化(动态) int pthread_cond_signal(pthread_cond_t *); //设置信号 int pthread_cond_timedwait(pthread_cond_t *restrict, //超时等待 pthread_mutex_t *restrict, const struct timespec *restrict); int pthread_cond_wait(pthread_cond_t *restrict, //等待信号(阻塞) pthread_mutex_t *restrict); int pthread_cond_destroy(pthread_cond_t *); //删除条件变量 int pthread_cond_broadcast(pthread_cond_t *); //信号广播
例程:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <pthread.h> pthread_mutex_t test_th_mutex; pthread_cond_t test_th_cond; #define TH_LOCK_INIT1() do { \ pthread_mutexattr_t attr; \ pthread_mutexattr_init(&attr); \ pthread_mutex_init(&test_th_mutex, &attr); \ } while (0) //pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP); \ //可重复进入临界区 #define TH_LOCK_INIT() pthread_mutex_init(&test_th_mutex, NULL) #define TH_LOCK() pthread_mutex_lock(&test_th_mutex) #define TH_UNLOCK() pthread_mutex_unlock(&test_th_mutex) #define TH_DESTROY() pthread_mutex_destroy(&test_th_mutex) #define TH_COND_WAIT() pthread_cond_wait(&test_th_cond,&test_th_mutex) #define TH_COND_SIGNAL() pthread_cond_signal(&test_th_cond) #define TH_COND_TIMEWAIT(time) pthread_cond_timedwait(&test_th_cond, &test_th_mutex, &time) #define TH_COND_BROADCAST() pthread_cond_broadcast(&test_th_cond) #define TH_COND_DESTROY() pthread_cond_destroy(&test_th_cond) #define TH_COND_INIT() pthread_cond_init(&test_th_cond, NULL) int set_th_cond_timedwait() { int ret = 0; struct timeval now; struct timespec time; long timeout_ms = 5; //+5ms gettimeofday(&now, NULL); long nsec =now.tv_usec * 1000 + (timeout_ms % 1000) * 1000000; time.tv_sec = now.tv_sec + 5; //+5秒 time.tv_nsec = nsec % 1000000000; //纳秒 ret = TH_COND_TIMEWAIT(time); //此时间不是几秒 而是某一时间 类似闹钟 printf("%d\n",ret); return ret; } void *test_thread() { int test_cn; int i = 0; TH_COND_INIT(); TH_LOCK_INIT(); sleep(10); printf("-----------------------test_th\n"); while(1) { TH_LOCK(); #if 0 TH_COND_WAIT(); #else set_th_cond_timedwait(); #endif i++; printf("---------------------test_th %d\n",i); TH_UNLOCK(); } TH_COND_DESTROY(); TH_DESTROY(); } void *test_thread1() { while(1) { printf("--------------------test tt\n"); TH_COND_SIGNAL(); //TH_COND_BROADCAST(); } } int test_th() { pthread_t ThreadId = {0}; pthread_t ThreadId1 = {0}; int ret = 0; ret = pthread_create(&ThreadId, NULL, test_thread, NULL); if(ret){ printf("pthread_create test_thread ret=%d\n", ret); return -1; } ret = pthread_create(&ThreadId, NULL, test_thread1, NULL); if(ret){ printf("pthread_create test_thread1 ret=%d\n", ret); return -1; } pthread_detach(ThreadId); pthread_detach(ThreadId1); return 0; } int main() { test_th(); return 0; }
结果
[17:44:50:894]:145 [17:44:50:894]:---------------------test_th 51 [17:44:55:886]:145 //超时返回值 [17:44:55:886]:---------------------test_th 52 [17:45:00:412]: [17:45:00:911]:---------------------test_th 53 [17:45:01:163]:--------------------test tt //TH_COND_SIGNAL [17:45:01:163]:0 [17:45:01:163]:---------------------test_th 54 [17:45:02:536]: [17:45:05:580]:--------------------test tt //TH_COND_SIGNAL [17:45:05:580]:0 [17:45:05:580]:---------------------test_th 55 [17:45:10:586]:145 [17:45:10:586]:---------------------test_th 56
参考:
https://www.cnblogs.com/roger-yu/p/6163712.html
http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/pthread.h.html