0、互斥量

 Windows下的互斥量

是个内核对象,每次WaitForSingleObject和ReleaseMutex时都会检查当前线程ID和占有互斥量的线程ID是否一致。

当多次Wait**时就要对应多次ReleaseMutex, 当ReleaseMutex过多次数时如果发现当前占有互斥量的线程ID和当前调用ReleaseMutex的线程ID不一致时仅仅返回FLASE,GetLastError返回ERROR_NOT_OWNER,没有其他副作用。

当占有mutex的线程在Release之前退出时,该mutex被【遗弃】,此时系统自动收回mutex,可供其他线程申请。

允许多次等待

WaitForSingleObject(hMutex, time);

WaitForSingleObject(hMutex, itme);

多次等待 对应多次释放

ReleaseMutex(hMutex);

ReleaseMutex(hMutex);

Linux下的互斥量

可以设置互斥量的属性是否为可以被同一个线程多次lock,  还可以设置该互斥量的范围,即是用于进程之间同步 还是 同一进程不同线程之间的同步。

相关API 将说明见代码注释部分。

1、相关API

//Initialize a mutex with attribute(can be NULL)
int pthread_mutex_init(
pthread_mutex_t* mutex,
const pthread_mutexattr_t* mutexattr); //lock a mutex
int pthread_mutex_lock(pthread_mutex_t* mutex); //ulock a mutex
int pthread_mutex_unlock(pthread_mutex_t* mutex); //destroy a mutex
int pthread_mutex_destroy(pthread_mutex_t* mutex); int pthread_mutexattr_setpshared(
pthread_mutexattr_t* mattr,
int pshared //PTHREAD_PROCESS_SHARE | PTHREAD_PROCESS_PRIVATE
); int pthread_mutexattr_getshared(
pthread_mutexattr_t* mattr,
int* pshared); int pthread_mutexattr_settype(
pthread_mutexattr_t* attr,
int type //PTHREAD_MUTEX_TIMED_NP -- default value
//PTHREAD_MUTEX_RECURISIVE_NP -- allow a thread lock multitimes
//PTHREAD_MUTEX_ERRORCHECK_NO -- check error lock, return EDEADLK if the same thread want to LOCK
//PTHREAD_MUTEX_ADAPTIVE_NO -- adaptive lock, the simplest lock
) int pthread_mutexattr_gettype(
pthread_mutexattr_t* attr,
int* type
)

2、demo

#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <errno.h> using namespace std; /***********************************************
*
* Initialize a mutex with attribute(can be NULL)
* int pthread_mutex_init(
* pthread_mutex_t* mutex,
* const pthread_mutexattr_t* mutexattr);
*
* lock a mutex
* int pthread_mutex_lock(pthread_mutex_t* mutex);
*
* unlock a mutex
* int pthread_mutex_unlock(pthread_mutex_t* mutex);
*
* destroy a mutex
* int pthread_mutex_destroy(pthread_mutex_t* mutex);
*
* int pthread_mutexattr_setpshared(
* pthread_mutexattr_t* mattr,
* int pshared //PTHREAD_PROCESS_SHARE | PTHREAD_PROCESS_PRIVATE
* );
*
* int pthread_mutexattr_getshared(
* pthread_mutexattr_t* mattr,
* int* pshared);
*
* int pthread_mutexattr_settype(
* pthread_mutexattr_t* attr,
* int type //PTHREAD_MUTEX_TIMED_NP -- default value
* //PTHREAD_MUTEX_RECURISIVE_NP -- allow a thread lock multitimes
* //PTHREAD_MUTEX_ERRORCHECK_NO -- check error lock, return EDEADLK if the same thread want to LOCK
* //PTHREAD_MUTEX_ADAPTIVE_NO -- adaptive lock, the simplest lock
* )
*
*
* int pthread_mutexattr_gettype(
* pthread_mutexattr_t* attr,
* int* type
* )
* *********************************************/ void* work_thread(void* p)
{
if (NULL == p)
return const_cast<char*>("invalid thread argument"); pthread_mutex_t* pMutex = (pthread_mutex_t*)(p); //current thread ID
pthread_t nThreadID = pthread_self(); int i = ;
while(++ i <= )
{
//lock multi times
pthread_mutex_lock(pMutex);
pthread_mutex_lock(pMutex); cout << "Thread " << nThreadID << " is Running! " << endl; //and so unlock multi times
pthread_mutex_unlock(pMutex);
pthread_mutex_unlock(pMutex);
usleep( * ); //1 miliseconds
} return const_cast<char*>("------ finish -----------"); } void* work_thread2(void* p)
{
if (NULL == p)
return const_cast<char*>("invalid thread argument"); pthread_mutex_t* pMutex = (pthread_mutex_t*)(p); //current thread ID
pthread_t nThreadID = pthread_self(); int i = ;
while(++ i <= )
{
//if current thread can not enter mutex,
//and the function pthread_mutex_trylock will RETURN Immediatly
if ( EBUSY == pthread_mutex_trylock(pMutex))
cout << "Other thread is lock the resouce, i am waiting.." << endl;
else
{
cout << "Thread " << nThreadID << " is Running! " << endl;
pthread_mutex_unlock(pMutex);
usleep( * ); //1 miliseconds
} }
return const_cast<char*>("------ finish -----------"); } int main()
{
const size_t nThreadCount = ;
pthread_t threadIDs[nThreadCount];
int nRet = -;
pthread_mutex_t mutex;
pthread_mutexattr_t mutexattr;
void* pRet = NULL; //thread return value //allow a thread lock multi times
nRet = pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE_NP); nRet = pthread_mutex_init(&mutex, &mutexattr);
if ( != nRet)
return -; for (size_t i = ; i < nThreadCount - ; ++ i)
{
nRet = pthread_create(&threadIDs[i], NULL, work_thread, (void*)(&mutex));
if ( != nRet)
continue;
} nRet = pthread_create(&threadIDs[nThreadCount - ], NULL, work_thread2, (void*)(&mutex));
if ( != nRet)
cerr << endl << "work_thread2 created falied! " << endl; for (size_t i = ; i < nThreadCount; ++ i)
{
nRet = pthread_join(threadIDs[i], &pRet);
if ( == nRet)
{
cout << " Thread " << threadIDs[i] << " Finished ! " \
" It's return value is " << (char*)pRet << endl;
} } pthread_mutex_destroy(&mutex); return ;
}

3、执行结果

最新文章

  1. EasyUI中在表单提交之前进行验证
  2. Direct2D开发:从资源加载位图
  3. ubuntu14.04字符界面中文乱码及中文输入
  4. webservice注释
  5. HTML5 学习
  6. strut2服务器与android交互数据
  7. CocoaChina 第四个测试
  8. 更改JFram标题栏图标
  9. LuaFramework内存资源管理器ResourceManger详解及切换场景资源清理
  10. 微信小程序ios点击状态栏返回顶部不好使
  11. matlab中如何用rand产生相同的随机数
  12. Nestjs 缓存
  13. ArrayList add方法(转)
  14. kafka可视化客户端工具(Kafka Tool)的基本使用
  15. RNN生产唐诗
  16. Zookeeper面试题
  17. Windows10中以管理员身份打开命令提示符
  18. HBase shell 命令。
  19. wpf中把按钮变成圆角
  20. Unity 编辑器扩展 Chapter2—Gizmos

热门文章

  1. MyBatis学习总结_12_Mybatis+Mysql分页查询
  2. iOS:UIAlertController和UIAlertAction的详解
  3. JVM生产环境参数实例及分析
  4. linux环境下,利用tc限制两台服务器间的网速,非常简单。
  5. 使用git建立本地仓储管理代码【转】
  6. HDU 4752 Polygon(抛物线长度积分)
  7. MySQL之Join
  8. 《OD学hadoop》Linux基础
  9. hdu 5718 Oracle 高精度
  10. 【转载】关于XML文档的xmlns、xmlns:xsi和xsi:schemaLocation