线程同步中的锁和信号量

由于工作上用到线程之间的同步,而且有超时处理,问题是:子主线程等待的时候已经加锁了,为什么主线程中还可以再去加锁给子线程发送信号呢?
pthread_cond_timedwait()函数有三个入口参数:
  1. pthread_cond_t __cond:条件变量(触发条件)
  2. pthread_mutex_t __mutex: 互斥锁
  3. struct timespec __abstime: 等待时间(其值为系统时间 + 等待时间)
当在指定时间内有信号传过来时,pthread_cond_timedwait()返回0,否则返回一个非0数;
在使用pthread_cond_timedwait()函数时,必须有三步:
  1. 加互斥锁:pthread_mutex_lock(&__mutex)
  2. 等待:pthread_cond_timedwait(&__cond, &__mutex, &__abstime) //解锁->等待->加锁
  3. 解互斥锁:pthread_mutex_unlock(&__mutex)
发送信号量时,也要有三步:
  1. 加互斥锁:pthread_mutex_lock(&__mutex)
  2. 发送:pthread_cond_signal(&__cond)
  3. 解互斥锁: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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值