tars源码漫谈第17篇------tc_thread_cond.h/tc_thread_cond.cpp(条件变量)

      在tc_thread_cond.cpp中有#include "util/tc_timeprovider.h", 这个仅仅是为了获取时间, 先忽略。

      TC_ThreadCond这个类是对基本的线程条件基本的api操作的封装, 并没有新意。 来写一个代码, 熟悉下线程的“条件变量”,实现线程同步, 顺便掌握整个TC_ThreadCond:

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

int a = 1;
int b = 2;

void* threadFunc(void* p)
{
	printf("in threadFunc\n");
	sleep(5);

	pthread_mutex_lock(&mutex);
	printf("in threadFunc lock\n");
	a = 20;
	b = 10;
	pthread_mutex_unlock(&mutex); 
	
	pthread_cond_broadcast(&cond);  // 发送信号(也可以用pthread_cond_signal), 让pthread_cond_wait获取到"线程条件"
	
	return NULL;
}
 
int main()
{
	pthread_t id;
	pthread_create (&id, NULL, threadFunc, NULL);
	
	pthread_mutex_lock(&mutex);
	while (a <= b) 
	{
		sleep(1);
		printf("in while\n");
		pthread_cond_wait(&cond, &mutex); // 函数调用后,阻塞住,释放锁;  获取"线程条件"后,线程会唤醒,函数返回,并获取到锁。
	}
	
	printf("out while\n");
	pthread_mutex_unlock(&mutex);
	
	printf("to end\n");
	getchar();
 
	return 0;
}

       结果:

ubuntu@VM-0-15-ubuntu:~/taoge/cpp$ g++ test.cpp -lpthread
ubuntu@VM-0-15-ubuntu:~/taoge/cpp$ ./a.out 
in threadFunc
in while
in threadFunc lock
out while
to end

      解释一下: 进入main函数主线程, 随后线程threadFunc抢占先机, 然后sleep时, 切回主线程, 进入锁区的while,  然后pthread_cond_wait阻塞住, 又转移到threadFunc线程, 在锁区改变a, b的值, 出锁区后, 利用pthread_cond_broadcast广播信号, 唤醒pthread_cond_wait, pthread_cond_wait返回后, 获取到锁, 进而有能力跳出while循环, 然后出锁区, 进而到getchar处。 流程便是如此。

      apue中有一个很好的例子, 执行任务的线程在循环wait,  添加任务的线程会signal,  一个发号施令, 一个干活。 你情我愿。

 

 

       

      再看:

timespec TC_ThreadCond::abstime( int millsecond) const
{
    struct timeval tv;

    //gettimeofday(&tv, 0);
    TC_TimeProvider::getInstance()->getNow(&tv);

    int64_t it  = tv.tv_sec * (int64_t)1000000 + tv.tv_usec + (int64_t)millsecond * 1000;

    tv.tv_sec   = it / (int64_t)1000000;
    tv.tv_usec  = it % (int64_t)1000000;

    timespec ts;
    ts.tv_sec   = tv.tv_sec;
    ts.tv_nsec  = tv.tv_usec * 1000; 
      
    return ts; 
}

      总觉得ts.tv_nsec  = tv.tv_usec * 1000 理论上可能会溢出,不过apue就是这么写的!   但我觉得最好还是先强转下。

 

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值