今天有朋友咨询pthread_cond_timedwait的使用方法.为保证跨平台,线程库建议使用pthread,不论是windows还是linux都可以编译.
pthread win32主页
注意:虽然名字叫pthread win32,但是支持windows x64和windows x32
windows pthread下载
pthread_cond_timedwait还需要gettimeofday函数,但是windows上没有这个函数,需要自己定义:
#include <Windows.h>
#define FILETIME_UNITS_PER_SEC 10000000L
#define FILETIME_UNITS_PER_USEC 10
int gettimeofday(struct timeval* tp, struct timezone* tzp) {
//https://docs.microsoft.com/zh-cn/windows/win32/api/minwinbase/ns-minwinbase-filetime?redirectedfrom=MSDN
//FILETIME structure:Contains a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC).
// epoch =1970-01-01 - 1601-01-01 = 116444736000000000ULL; (why 1601?)
static const unsigned __int64 epoch = 116444736000000000ULL;
FILETIME file_time;
ULARGE_INTEGER ularge;
GetSystemTimeAsFileTime(&file_time);
ularge.LowPart = file_time.dwLowDateTime;
ularge.HighPart = file_time.dwHighDateTime;
tp->tv_sec = (long)((ularge.QuadPart - epoch) / FILETIME_UNITS_PER_SEC);
tp->tv_usec = (long)(((ularge.QuadPart - epoch) % FILETIME_UNITS_PER_SEC)
/ FILETIME_UNITS_PER_USEC);
return 0;
}
重点
- struct timeval中的tv_sec时间单位是秒, tv_usec的时间单位是微秒;
- struct timezone在Windows上无用,windows内核时钟只精确至毫秒;
- 1秒=1000毫秒=1000000微秒=1000000000纳秒
使用方法
struct timeval now;
struct timespec abstime;
int32_t ms = 100; //休眠100毫秒
gettimeofday(&now, NULL);
abstime.tv_sec = now.tv_sec;
//now.tv_usec * 1000微秒转换为纳秒
//(ms % 1000) * 1000000 毫秒转换为纳秒,其中毫秒的值不能超过1000
abstime.tv_nsec = now.tv_usec * 1000 + (ms % 1000) * 1000000;
pthread_mutex_lock(mutex);
pthread_cond_timedwait(cond, mutex,&abstime); --注意在休眠过程中锁已经释放,休眠结束后又重新锁定
pthread_mutex_unlock(mutex);