【Linux】Mutex互斥量线程同步的例子
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、执行结果

【Linux】Mutex互斥量线程同步的例子的更多相关文章
- 【Linux】Semaphore信号量线程同步的例子
0. 信号量 Linux下的信号量和windows下的信号量稍有不同. Windows Windows下的信号量有一个最大值和一个初始值,初始值和最大值可以不同. 而且Windows下的信号量是一个 ...
- Linux并发与同步专题 (4) Mutex互斥量
关键词:mutex.MCS.OSQ. <Linux并发与同步专题 (1)原子操作和内存屏障> <Linux并发与同步专题 (2)spinlock> <Linux并发与同步 ...
- c# Thread5——线程同步之基本原子操作。Mutex互斥量的使用
之前的博文也说到了如果多线程对于访问的公共资源操作都是原子操作,那么可以避免竞争条件.关于多线程的竞争可以百度. 1.执行最基本的原子操作 c#提供了一系列供我们使用的原子操作的方法和类型,比如我们的 ...
- linux系统编程:线程同步-相互排斥量(mutex)
线程同步-相互排斥量(mutex) 线程同步 多个线程同一时候訪问共享数据时可能会冲突,于是须要实现线程同步. 一个线程冲突的演示样例 #include <stdio.h> #includ ...
- C++多线程同步之Mutex(互斥量)
原文链接: http://blog.csdn.net/olansefengye1/article/details/53086141 一.互斥量Mutex同步多线程 1.Win32平台 相关函数和头文件 ...
- Linux 多线程互斥量互斥
同步 同一个进程中的多个线程共享所在进程的内存资源,当多个线程在同一时刻同时访问同一种共享资源时,需要相互协调,以避免出现数据的不一致和覆盖等问题,线程之间的协调和通信的就叫做线程的同步问题, 线程同 ...
- Linux学习笔记21——线程同步的两种方式
一 用信号量同步 1 信号量函数的名字都以sem_开头,线程中使用的基本信号量函数有4个 2 创建信号量 #include<semaphore.h> int sem_init(sem_t ...
- linux学习笔记之线程同步机制
一.基础知识. 1:线程同步机制:互斥量,读写锁,条件变量,自旋锁,屏障. 1,互斥量:每个进程访问被互斥量保护的资源时,都需要先对互斥量进行判断. 1)互斥量重要属性:进程共享属性,健壮属性,类型属 ...
- Linux下C的线程同步机制
C里提供了保证线程安全性的三种方法: (添加头文件#include<pthread.h>,pthread 库不是 Linux 系统默认的库,连接时需要使用静态库 libpthread.a, ...
随机推荐
- 关于Linux操作系统下文件特殊权限的解释
文件特殊权限的解释. -rwsr-xr-x = 4755 文件执行的时候,会以owner的身份来执行,就是setuid . 例如:-rwxr-xr-t 1 root wheel 0 7 9 18:24 ...
- git checkout not discard changes
1. checkout one branch, show status user@vbox:/mnt/tmp$ git checkout masterSwitched to branch 'maste ...
- JNI层问题
1. make:进入目录'/opt/FriendlyARM/tiny4412/android/android-4.1.2'make: *** 没有规则可以创建“out/target/product/g ...
- CFileDialog使用总结
http://blog.csdn.net/tianhai110/article/details/2055149 CFileDialog经常用,但经常忘,现归纳整理下,方便今后查询. 例子: CFile ...
- Python3 学习第十弹: 模块学习三之数字处理
math模块 提供基础的数学函数, cos(3.14) = -0.999..(弧度制) acos(1) = 0.0 sqrt(9) = 3.0 degrees(3.14) = 179.9999..(弧 ...
- Struts2 原理
.Struts2原理 .Struts 1 原理 .Struts1 和webwork的关系 .HttpServletRequest Struts2原理
- easyui tree 模仿ztree 使用扁平化加载json
1,载入扩展JS //作者孙宇 //自定义loadFilter的实现 $.fn.tree.defaults.loadFilter = function (data, parent) { var opt ...
- asp.net webpage
一.服务器脚本基础介绍 首先,我们先复习一下Web服务器页面的基本执行方式: 1. 客户端通过在浏览器的地址栏敲入地址来发送请求到服务器端 2. 服务器接收到请求之后,发给相应的服务器端页面(也就是脚 ...
- spring、springmvc、mybatis整合笔记
这段时间上一个项目刚做完,下一个项目还没开始,趁这个时候来认真总结一下上个项目使用的ssm开发框架.由于,项目中关于使用ssm这部分的代码和配置是我们项目的整体架构师一个独立完成的,我们只负责业务部分 ...
- zipline
history 多只股票时会返回某几只股票停牌没数据 if not symbol(stock) in data: 聚宽 多只股票如果某几只没有发行 600485: nan 多只股票如果某几只停牌 60 ...