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互斥量线程同步的例子的更多相关文章

  1. 【Linux】Semaphore信号量线程同步的例子

    0. 信号量 Linux下的信号量和windows下的信号量稍有不同. Windows Windows下的信号量有一个最大值和一个初始值,初始值和最大值可以不同.  而且Windows下的信号量是一个 ...

  2. Linux并发与同步专题 (4) Mutex互斥量

    关键词:mutex.MCS.OSQ. <Linux并发与同步专题 (1)原子操作和内存屏障> <Linux并发与同步专题 (2)spinlock> <Linux并发与同步 ...

  3. c# Thread5——线程同步之基本原子操作。Mutex互斥量的使用

    之前的博文也说到了如果多线程对于访问的公共资源操作都是原子操作,那么可以避免竞争条件.关于多线程的竞争可以百度. 1.执行最基本的原子操作 c#提供了一系列供我们使用的原子操作的方法和类型,比如我们的 ...

  4. linux系统编程:线程同步-相互排斥量(mutex)

    线程同步-相互排斥量(mutex) 线程同步 多个线程同一时候訪问共享数据时可能会冲突,于是须要实现线程同步. 一个线程冲突的演示样例 #include <stdio.h> #includ ...

  5. C++多线程同步之Mutex(互斥量)

    原文链接: http://blog.csdn.net/olansefengye1/article/details/53086141 一.互斥量Mutex同步多线程 1.Win32平台 相关函数和头文件 ...

  6. Linux 多线程互斥量互斥

    同步 同一个进程中的多个线程共享所在进程的内存资源,当多个线程在同一时刻同时访问同一种共享资源时,需要相互协调,以避免出现数据的不一致和覆盖等问题,线程之间的协调和通信的就叫做线程的同步问题, 线程同 ...

  7. Linux学习笔记21——线程同步的两种方式

    一  用信号量同步 1 信号量函数的名字都以sem_开头,线程中使用的基本信号量函数有4个 2 创建信号量 #include<semaphore.h> int sem_init(sem_t ...

  8. linux学习笔记之线程同步机制

    一.基础知识. 1:线程同步机制:互斥量,读写锁,条件变量,自旋锁,屏障. 1,互斥量:每个进程访问被互斥量保护的资源时,都需要先对互斥量进行判断. 1)互斥量重要属性:进程共享属性,健壮属性,类型属 ...

  9. Linux下C的线程同步机制

    C里提供了保证线程安全性的三种方法: (添加头文件#include<pthread.h>,pthread 库不是 Linux 系统默认的库,连接时需要使用静态库 libpthread.a, ...

随机推荐

  1. JS解析json数据

    JS解析json数据(如何将json字符串转化为数组) 1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN&q ...

  2. Ubuntu 14.10下安装深度音乐客户端

    很多刚从windows系统投靠到ubuntu的机油,在听音乐时不是很舒心.毕竟ubuntu软件中心的很多影音软件都是国外的朋友编写的,所以很多时候国内的朋友用着很不舒服.今天给大家推荐的是国内开发者针 ...

  3. js之dom_1

    DOM    ie中有dom对象都是com对象的形式实现的    操作dom时,要注意返回的节点列表.属性列表都是动态的,会随着操作的改变而实时改变    document.getElementByI ...

  4. Java编程思想 (1~10)

    [注:此博客旨在从<Java编程思想>这本书的目录结构上来检验自己的Java基础知识,只为笔记之用] 第一章 对象导论 1.万物皆对象2.程序就是对象的集合3.每个对象都是由其它对象所构成 ...

  5. 淘宝主搜索离线集群完成Hadoop 2

    淘宝搜索离线dump集群(hadoop&hbase)2013进行了几次重大升级,本文中将这些升级的详细过程.升级中所遇到的问题以及这些问题的解决方案分享给大家.至此,淘宝主搜索离线集群完全进入 ...

  6. Http进行网络通信

    http使用get的方式进行网络通信: package com.testGet; import java.io.BufferedReader; import java.io.IOException; ...

  7. LeetCode Longest Common Prefix 最长公共前缀

    题意:给多个字符串,返回这些字符串的最长公共前缀. 思路:直接逐个统计同一个位置上的字符有多少种,如果只有1种,那么就是该位是相同的,进入下一位比较.否则终止比较,返回前缀.可能有一个字符串会比较短, ...

  8. Annotation(jdk5.0注解)复习(转自http://3w_cnblogs_com/pepcod/)

    package annotation.test; import java.lang.annotation.ElementType; import java.lang.annotation.Retent ...

  9. 朴素贝叶斯(Naive Bayes)

    1.朴素贝叶斯模型 朴素贝叶斯分类器是一种有监督算法,并且是一种生成模型,简单易于实现,且效果也不错,需要注意,朴素贝叶斯是一种线性模型,他是是基于贝叶斯定理的算法,贝叶斯定理的形式如下: \[P(Y ...

  10. Eclipse 打开编辑文件所在文件夹方法

    一个便捷的方法在eclipse的菜单中,依次点击Run->External Tools-> External Tools configurations添加一个新的工具 OpenContai ...