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