在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就是这么写的! 但我觉得最好还是先强转下。