主要函数说明
- int pthread_mutex_init (pthread_mutex_t *__mutex,const pthread_mutexattr_t *__mutexattr)创建一个锁;
- int pthread_mutex_destroy (pthread_mutex_t *__mutex)销毁锁;
- int pthread_mutex_trylock (pthread_mutex_t *__mutex)尝试去lock,lock不到时立即返回错误;
- int pthread_mutex_lock (pthread_mutex_t *__mutex)尝试去lock,lock不到时永久等待;
- int pthread_mutex_timedlock (pthread_mutex_t *__restrict __mutex, const struct timespec *__restrict __abstime)尝试去lock,lock不到时等待__abstime的时间;
- int pthread_mutex_unlock (pthread_mutex_t *__mutex)释放一个锁;
- int pthread_mutexattr_init (pthread_mutexattr_t *__attr)初始化锁参数;
- int pthread_mutexattr_destroy (pthread_mutexattr_t *__attr)销毁锁参数
- int pthread_mutexattr_setpshared (pthread_mutexattr_t *__attr,int __pshared)设定锁的进程共享属性;
- int pthread_mutexattr_settype (pthread_mutexattr_t *__attr, int __kind)设定锁的加锁类型;
- int pthread_mutexattr_setprotocol (pthread_mutexattr_t *__attr,int __protocol)设定锁对线程优先级的影响策略;
互斥锁使用示例
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
#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:%un", count);
msDelay_select(200);
DBG_PRINT("End :%un", count);
/**
* 释放锁;
*/
pthread_mutex_unlock(&mutexID);
msDelay_select(10);
}
}
static void *_testThread2(void* arg)
{
while(1)
{
pthread_mutex_lock(&mutexID);
DBG_PRINT("Start:%un", count);
msDelay_select(100);
DBG_PRINT("End :%un", 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("KOn");
/**
* 必须在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:%sn", 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:%sn", 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()后销毁了锁,打印如下图:
会发现两个线程的打印有出现交叉;
使用互斥锁的一些注意事项
- 如果已经创建锁pthread_mutex_t 类型的锁A,然后定义pthread_mutex_t 类型的锁B,不要直接将A赋值给B,然后再使用pthread_mutex_lock(&B)的方式去获取锁,这样是非法的,pthread_mutex_lock会直接返回失败;
- 也不要使用memcpy(&B, &A, sizeof(pthread_mutex_t )),然后调用pthread_mutex_lock(&B)的方式去获取锁;这样也没办法成功lock;
- 为了安全起见,无论在何种mutex type下,请保证锁的lock与unlock在同一个线程下,一定是成对调用;当然pthread_mutex_trylock和pthread_mutex_timedlock返回失败时,不要调用pthread_mutex_unlock;
- 尽量减少锁的粒度;同一把锁,尽量在同一个.c中使用;如果其他地方迫不得已也需要使用该锁(如在嵌入式平台对某些硬件资源访问),也尽量在锁定义处封装一个API extern给其他地方使用;
© 版权声明
转载请注明出处,并标明原文链接。
本网站尊重知识产权,如有侵权,请及时联系我们删除。
本站所有原创内容仅用于学习和交流目的,未经作者和本站授权不得进行商业使用或盈利行为。
本网站尊重知识产权,如有侵权,请及时联系我们删除。
本站所有原创内容仅用于学习和交流目的,未经作者和本站授权不得进行商业使用或盈利行为。
THE END
暂无评论内容