由于工作上用到线程之间的同步,而且有超时处理,问题是:子主线程等待的时候已经加锁了,为什么主线程中还可以再去加锁给子线程发送信号呢?
pthread_cond_timedwait()函数有三个入口参数:
- pthread_cond_t __cond:条件变量(触发条件)
- pthread_mutex_t __mutex: 互斥锁
- struct timespec __abstime: 等待时间(其值为系统时间 + 等待时间)
当在指定时间内有信号传过来时,pthread_cond_timedwait()返回0,否则返回一个非0数;
在使用pthread_cond_timedwait()函数时,必须有三步:
- 加互斥锁:pthread_mutex_lock(&__mutex)
- 等待:pthread_cond_timedwait(&__cond, &__mutex, &__abstime) //解锁->等待->加锁
- 解互斥锁:pthread_mutex_unlock(&__mutex)
发送信号量时,也要有三步:
- 加互斥锁:pthread_mutex_lock(&__mutex)
- 发送:pthread_cond_signal(&__cond)
- 解互斥锁:pthread_mutex_unlock(&__mutex)
问题解答:其实这是因为在pthread_cond_timedwait()函数中已经对互斥锁进行解锁操作了,所以这个时候发送信号量是不会阻塞的。
测试代码:
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <semaphore.h>
#include <sys/time.h>
#define SENDSIGTIME 3
pthread_cond_t g_cond;
pthread_mutex_t g_mutex;
char time_tmp[128] = "";
char *display_time(void){
struct timeval tv;
struct timezone tz;
struct tm *tp;
gettimeofday(&tv, &tz);
tp=localtime(&tv.tv_sec);
memset(time_tmp, 0, sizeof(time_tmp));
sprintf(time_tmp, "%4d-%02d-%02d %02d:%02d:%02d.%06d",1900+tp->tm_year, 1+tp->tm_mon, tp->tm_mday, tp->tm_hour, tp->tm_min, tp->tm_sec, (int)(tv.tv_usec));
return time_tmp;
}
void* thread_fun(void *arg){
int ret = 0;
struct timeval now;
struct timespec outtime;
printf("[%s] %s lock\n", display_time(), __FUNCTION__);
pthread_mutex_lock(&g_mutex);
gettimeofday(&now, NULL);
outtime.tv_sec = now.tv_sec + 5;
outtime.tv_nsec = now.tv_usec * 1000;
printf("[%s] %s wait\n", display_time(), __FUNCTION__);
ret = pthread_cond_timedwait(&g_cond, &g_mutex, &outtime);
//ret = pthread_cond_wait(&g_cond, &g_mutex);
printf("[%s] %s recv signal ret:%d\n", display_time(), __FUNCTION__, ret);
pthread_mutex_unlock(&g_mutex);
printf("[%s] %s unlock end\n", display_time(), __FUNCTION__);
}
int main(int argc, char* argv[]){
pthread_t pid;
int ret;
pthread_cond_init(&g_cond, NULL);
pthread_mutex_init(&g_mutex, NULL);
ret = pthread_create(&pid, NULL, (void *)thread_fun, NULL);
if (0 != ret){
perror("create thread!\n");
return 1;
}
printf("[%s] %s Wait %ds send signal\n", display_time(), __FUNCTION__, SENDSIGTIME);
sleep(SENDSIGTIME);
printf("[%s] %s Lock\n", display_time(), __FUNCTION__);
pthread_mutex_lock(&g_mutex);
printf("[%s] %s Send signal\n", display_time(), __FUNCTION__);
pthread_cond_signal(&g_cond);
printf("[%s] %s Send signal end\n", display_time(), __FUNCTION__);
pthread_mutex_unlock(&g_mutex);
printf("[%s] %s Send unlock end\n", display_time(), __FUNCTION__);
pthread_join(pid, NULL);
pthread_cond_destroy(&g_cond);
pthread_mutex_destroy(&g_mutex);
return 0;
}
运行结果: