#include
#include
#include
#include
#include
#include
#include
#define DBG_PRINT(fmt, args...) {printf("%s %d ", __FUNCTION__, __LINE__);printf(fmt,##args);}
/**
* [msDelay_select 用select()实现的ms级别线程休眠]
* @param msTime [休眠线程msTime时间,单位毫秒]
*/
void msDelay_select(unsigned msTime)
{
struct timeval time;
if(msTime == 0)
{
DBG_PRINT("delay time can not be 0!\n");
return;
}
if(msTime>=1000)
{
time.tv_sec = msTime/1000;
time.tv_usec = (unsigned long)(msTime%1000)*1000UL;
}
else
{
time.tv_sec = 0;
time.tv_usec = (unsigned long)msTime*1000UL;
}
select(0, NULL, NULL, NULL, &time);
}
static pthread_mutexattr_t mutexAttr;
static pthread_mutex_t mutexID;
volatile static unsigned count = 0;
static pthread_once_t once_control = PTHREAD_ONCE_INIT;
static void *_testThread1(void* arg)
{
while(1)
{
/**
* 永久等待锁mutexID;
* pthread_mutex_trylock()则是尝试获取锁,如果lock失败立即返回错误;
* pthread_mutex_timedlock()以设定的最长时间去等待锁,超时直接返回错误;
*/
pthread_mutex_lock(&mutexID);
DBG_PRINT("Start:%u\n", count);
msDelay_select(200);
DBG_PRINT("End :%u\n", count);
/**
* 释放锁;
*/
pthread_mutex_unlock(&mutexID);
msDelay_select(10);
}
}
static void *_testThread2(void* arg)
{
while(1)
{
pthread_mutex_lock(&mutexID);
DBG_PRINT("Start:%u\n", count);
msDelay_select(100);
DBG_PRINT("End :%u\n", count);
pthread_mutex_unlock(&mutexID);
msDelay_select(10);
}
}
static void _mutexAttr_init_test(void)
{
/**
*初始化锁的参数;
*/
pthread_mutexattr_init(&mutexAttr);
//设定为PTHREAD_PROCESS_SHARED则可以进程间共享此mutex;
//PTHREAD_PROCESS_PRIVATE则只能在创建锁的进程使用;
pthread_mutexattr_setpshared(&mutexAttr, PTHREAD_PROCESS_PRIVATE);
/**
* 设定为PTHREAD_MUTEX_NORMAL,如果重复lock,就会死锁;
* 设定为PTHREAD_MUTEX_DEFAULT效果同上;
* 设定为PTHREAD_MUTEX_ERRORCHECK,会检测死锁,如果重复lock,直接返回错误;
* 设定为PTHREAD_MUTEX_RECURSIVE,可以重复lock,且对同一线程重复的lock,那么必须由该线程做同样次数的unlock,
* 并且如果尝试unlock其他线程lock的mutex,会直接返回错误,该效果只能使用在PTHREAD_PROCESS_PRIVATE锁的情况;
*/
pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_NORMAL);
/**
* 设定锁是否会影响线程调度的优先级;
* PTHREAD_PRIO_NONE,锁不影响线程调度优先级;
* PTHREAD_PRIO_INHERIT,当高优先级线程A需要低优先级线程B lock住的锁时,则B以A的优先级运行;
* 解锁之后,B线程恢复到自己的优先级运行;
* PTHREAD_PRIO_PROTECT,拥有锁的线程将以所有等待该锁线程的最高优先级运行;
* PTHREAD_PRIO_INHERIT和PTHREAD_PRIO_PROTECT只有在线程以RR或者FIFO这两种调度mode下才起作用;
*/
pthread_mutexattr_setprotocol(&mutexAttr, PTHREAD_PRIO_NONE);
}
/**
* [mutex_destroy 只运行一次锁销毁]
*/
void mutex_destroy(void)
{
int ret = 0;
DBG_PRINT("KO\n");
/**
* 必须在unlock状态下才能调用pthread_mutex_destroy销毁锁;
* 不然pthread_mutex_destroy会返回EBUSY;
*/
pthread_mutex_lock(&mutexID);
pthread_mutex_unlock(&mutexID);
ret = pthread_mutex_destroy(&mutexID);
if(ret != 0)
{
DBG_PRINT("The errno is:%s\n", strerror(ret));
return;
}
/**
* 销毁锁创建参数;
*/
pthread_mutexattr_destroy(&mutexAttr);
}
int main(int argc, const char* argv[])
{
pthread_t thread1ID, thread2ID;
int ret = 0;
_mutexAttr_init_test();
/**
* 创建锁,成功返回0;
*/
if(0!=(ret=pthread_mutex_init(&mutexID, &mutexAttr)))
{
DBG_PRINT("create mutex failed! errno:%s\n", strerror(ret));
return -1;
}
pthread_create(&thread1ID, NULL, _testThread1, NULL);
pthread_detach(thread1ID);
pthread_create(&thread2ID, NULL, _testThread2, NULL);
pthread_detach(thread2ID);
while(1)
{
count++;
msDelay_select(300);
if(count>10)
pthread_once(&once_control, mutex_destroy);
}
return 0;
}
编译运行后,结果如下图:
可以看到当没有运行mutex_destroy()时,_testThread1和_testThread2中的打印都是有序的,并没有出现这两个线程的打印交叉的情况;
当count大于10后,运行mutex_destroy()后销毁了锁,打印如下图:
会发现两个线程的打印有出现交叉;