在线程实际运行过程中,我们经常需要多个线程保持同步。这时可以用互斥锁来完成任务;互斥锁的使用过程中,主要有pthread_mutex_init,pthread_mutex_destory,pthread_mutex_lock,pthread_mutex_unlock这几个函数以完成锁的初始化,锁的销毁,上锁和释放锁操作。

一,锁的创建

锁可以被动态或静态创建,可以用宏PTHREAD_MUTEX_INITIALIZER来静态的初始化锁,采用这种方式比较容易理解,互斥锁是pthread_mutex_t的结构体,而这个宏是一个结构常量,如下可以完成静态的初始化锁:

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

另外锁可以用pthread_mutex_init函数动态的创建,函数原型如下:

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t * attr)

二,锁的属性

互斥锁属性可以由pthread_mutexattr_init(pthread_mutexattr_t *mattr);来初始化,然后可以调用其他的属性设置方法来设置其属性;

互斥锁的范围:可以指定是该进程与其他进程的同步还是同一进程内不同的线程之间的同步。可以设置为PTHREAD_PROCESS_SHARE和PTHREAD_PROCESS_PRIVATE。默认是后者,表示进程内使用锁。可以使用int pthread_mutexattr_setpshared(pthread_mutexattr_t *mattr, int pshared)

pthread_mutexattr_getshared(pthread_mutexattr_t *mattr,int *pshared)

用来设置与获取锁的范围;

互斥锁的类型:有以下几个取值空间:

  PTHREAD_MUTEX_TIMED_NP,这是缺省值,也就是普通锁。当一个线程加锁以后,其余请求锁的线程将形成一个等待队列,并在解锁后按优先级获得锁。这种锁策略保证了资源分配的公平性。

  PTHREAD_MUTEX_RECURSIVE_NP,嵌套锁,允许同一个线程对同一个锁成功获得多次,并通过多次unlock解锁。如果是不同线程请求,则在加锁线程解锁时重新竞争。

  PTHREAD_MUTEX_ERRORCHECK_NP,检错锁,如果同一个线程请求同一个锁,则返回EDEADLK,否则与PTHREAD_MUTEX_TIMED_NP类型动作相同。这样就保证当不允许多次加锁时不会出现最简单情况下的死锁。

  PTHREAD_MUTEX_ADAPTIVE_NP,适应锁,动作最简单的锁类型,仅等待解锁后重新竞争。

可以用
pthread_mutexattr_settype(pthread_mutexattr_t *attr , int type)
pthread_mutexattr_gettype(pthread_mutexattr_t *attr , int *type)

获取或设置锁的类型。

三,锁的释放

调用pthread_mutex_destory之后,可以释放锁占用的资源,但这有一个前提上锁当前是没有被锁的状态。

四,锁操作

对锁的操作主要包括加锁 pthread_mutex_lock()、解锁pthread_mutex_unlock()和测试加锁 pthread_mutex_trylock()三个。

  int pthread_mutex_lock(pthread_mutex_t *mutex)

  int pthread_mutex_unlock(pthread_mutex_t *mutex)

  int pthread_mutex_trylock(pthread_mutex_t *mutex)

  pthread_mutex_trylock()语义与pthread_mutex_lock()类似,不同的是在锁已经被占据时返回EBUSY而不是挂起等待

五,锁的使用

#include <pthread.h>
#include <stdio.h>  pthread_mutex_t mutex ;
void *print_msg(void *arg){  int i=0;  pthread_mutex_lock(&mutex);  //mutex加锁for(i=0;i<20;i++){  printf("output : %d\n",i);  usleep(200);  }  pthread_mutex_unlock(&mutex);  //mutex解锁
}
int main(int argc,char** argv)
{  pthread_t id1;  pthread_t id2;  pthread_mutex_init(&mutex,NULL);  pthread_create(&id1,NULL,print_msg,NULL);  pthread_create(&id2,NULL,print_msg,NULL);  pthread_join(id1,NULL);  //守护thread1结束pthread_join(id2,NULL);  //守护thread2结束pthread_mutex_destroy(&mutex);  return 0;
} 
#include <pthread.h>
#include <stdio.h>pthread_mutex_t mutex ;
void *print_msg(void *arg){int i=0;pthread_mutex_lock(&mutex);for(i=0;i<15;i++){printf("output : %d\n",i);usleep(100);}pthread_mutex_unlock(&mutex);
}
int main(int argc,char** argv){pthread_t id1;pthread_t id2;pthread_mutex_init(&mutex,NULL);pthread_create(&id1,NULL,print_msg,NULL);pthread_create(&id2,NULL,print_msg,NULL);pthread_join(id1,NULL);pthread_join(id2,NULL);pthread_mutex_destroy(&mutex);return 1;
}

将会一个线程一个线程的执行。

互斥锁mutex的使用方法相关推荐

  1. 多线程之互斥锁(mutex)的使用方法

    关于读写锁可查看:多线程之读写锁(unique_lock与shared_lock) 多个线程访问同一资源时,为了保证数据的一致性,最简单的方式就是使用 mutex(互斥锁). 引用 cpprefere ...

  2. android 线程互斥锁,线程锁(互斥锁Mutex)及递归锁

    一.线程锁(互斥锁) 在一个程序内,主进程可以启动很多个线程,这些线程都可以访问主进程的内存空间,在Python中虽然有了GIL,同一时间只有一个线程在运行,可是这些线程的调度都归系统,操作系统有自身 ...

  3. 互斥锁Mutex:鸿蒙轻内核中处理临界资源独占的“法官”

    摘要:本文带领大家一起剖析鸿蒙轻内核的互斥锁模块的源代码,包含互斥锁的结构体.互斥锁池初始化.互斥锁创建删除.申请释放等. 本文分享自华为云社区<鸿蒙轻内核M核源码分析系列十 互斥锁Mutex& ...

  4. 一文带你剖析LiteOS互斥锁Mutex源代码

    本文分享自华为云社区<LiteOS内核源码分析系列七 互斥锁Mutex>,原文作者:zhushy. 多任务环境下会存在多个任务访问同一公共资源的场景,而有些公共资源是非共享的临界资源,只能 ...

  5. 互斥锁(mutex lock)

    互斥锁 解决临界区最简单的工具就是互斥锁(mutex lock) 一个进程在进入临界区的时候获得锁(函数acquire) 在退出临界区时释放锁(函数release) 每个互斥锁都有一个布尔变量avai ...

  6. 互斥锁(mutex)

    原文地址:https://blog.csdn.net/qq_39736982/article/details/82348672 Linux中提供一把互斥锁mutex(也称之为互斥量). 每个线程在对资 ...

  7. php mutex,go互斥锁Mutex

    go mutex是互斥锁,只有Lock和Unlock两个方法,在这两个方法之间的代码不能被多个goroutins同时调用到. 看代码: package main import ( "fmt& ...

  8. 互斥锁(mutex)的使用

    互斥锁的使用范围: 互斥锁(Mutex)是在原子操作API的基础上实现的信号量行为.互斥锁不能进行递归锁定或解锁,能用于交互上下文但是不能用于中断上下文,同一时间只能有一个任务持有互斥锁,而且只有这个 ...

  9. 互斥锁 (mutex)

    定义互斥锁: struct mutex my_mutex; 初始化互斥锁: mutex_init(&my_mutex); 获取互斥锁: void mutex_lock(struct mutex ...

最新文章

  1. Linq的一些操作符-图表展示
  2. 消除软硬件鸿沟,芯客网完美支持智能硬件在移动互联时代的爆发
  3. how is Fiori launchpad host name and port number determine
  4. linux优盘驱动目录,Linux U盘加载阵列卡驱动步骤(.dd或img).doc
  5. 【nginx】关于Nginx的一些优化(突破十万并发)
  6. Flowable工作流入门
  7. vb中调用aspx页面
  8. CS48 D BIT
  9. Python 基础 —— time(时间,日期)
  10. HDU 1527 取石子游戏
  11. STOP: TOTAL NO. of ITERATIONS REACHED LIMIT.
  12. 数字化建筑与数字化建造,数字化建筑设计与建造
  13. 双容水箱液位串级控制系统的设计
  14. Android之Edittext禁止输入表情符号(雷惊风)
  15. RHCSA 核心考点列表
  16. 2019年9月省市区/县SQL数据——第二篇
  17. Windows实验——DNS劫持演练
  18. CCS编译优化与volatile
  19. Aptana Studio3安装方式
  20. python像数常用函数_八卦象数疗法的作用机理探讨

热门文章

  1. android webservice 简单应用
  2. 比tween更有效的tween包.
  3. Gentle中的数据表实体类相关自定义属性的设置和获得
  4. 真格量化-历史波动率
  5. 历时四年,给Google提交的Android Framework Bug终于被Fixed了
  6. Python--协程(gevent模块)
  7. 增量导出_[华为]一种实用的增量式深度CTR模型训练方法
  8. gpgga格式读取MATLAB,GPS编码格式及读取.doc
  9. TensorFlow 分布式
  10. Python 之 进程