线程同步中的锁和信号量

it2024-10-02  50

由于工作上用到线程之间的同步,而且有超时处理,问题是:子主线程等待的时候已经加锁了,为什么主线程中还可以再去加锁给子线程发送信号呢?

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; }

运行结果:

最新回复(0)