Pthread线程 —— 多线程同步 互斥锁(mutex)
来源:互联网 发布:域名网 编辑:程序博客网 时间:2024/06/09 16:56
多线程的同步机制
对于多线程程序来说,同步(synchronization)是指在一定的时间内只允许某一个线程访问某个资源 。而在此时间内,不允许其它的线程访问该资源。Linux下提供了多种方式来处理线程同步,最常用的是互斥锁(mutex)、条件变量(condition variable)和信号量(sem)。
互斥锁(mutex)
互斥锁是一个特殊的变量,它有锁上(lock)和打开(unlock)两个状态。互斥锁一般被设置成全局变量。打开的互斥锁可以由某个线程获得。一旦获得,这个互斥锁会锁上,此后只有该线程有权打开。其它想要获得互斥锁的线程,会等待直到互斥锁再次打开的时候。我们可以将互斥锁想像成为一个只能容纳一个人的洗手间,当某个人进入洗手间的时候,可以从里面将洗手间锁上。其它人只能在互斥锁外面等待那个人出来,才能进去。在外面等候的人并没有排队,谁先看到洗手间空了,就可以首先冲进去。
互斥锁的使用过程中,主要有pthread_mutex_init,pthread_mutex_destory,pthread_mutex_lock,pthread_mutex_unlock这几个函数以完成锁的初始化,锁的销毁,上锁和释放锁操作。
pthread_mutex_t 的定义:
typedef union{ struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner;#if __WORDSIZE == 64 unsigned int __nusers;#endif /* KIND must stay at this position in the structure to maintain binary compatibility. */ int __kind;#if __WORDSIZE == 64 int __spins; __pthread_list_t __list;#define __PTHREAD_MUTEX_HAVE_PREV 1#else unsigned int __nusers; __extension__ union { int __spins; __pthread_slist_t __list; };#endif } __data; char __size[__SIZEOF_PTHREAD_MUTEX_T]; long int __align;} pthread_mutex_t;
锁的创建
锁可以被动态或静态创建,可以用宏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_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); 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; }
总结
关于互斥锁,可能有些地方,不太容易懂。比如,互斥锁锁什么?简单的来说,互斥锁用的限制在同一时刻,其他的线程执行pthread_mutex_lock和pthread_mutex_unlock之间的指令。
- Pthread线程 —— 多线程同步 互斥锁(mutex)
- 同步线程—Mutex
- Pthread 线程 —— 多线程同步 条件变量(cond)
- 多线程之线程同步Mutex
- 线程间同步一 ———— 互斥锁(mutex)
- 线程、同步与锁——Mutex
- C++——多线程编程(二)std::mutex 线程同步、解决资源竞争问题
- 多线程5:经典线程同步 互斥量Mutex
- 多线程编程 sigaction ,mutex, pthread
- [C#学习笔记之多线程2]多线程同步与并发访问共享资源工具—Lock、Monitor、Mutex、Semaphore .
- 【PTHREAD】linux 多线程编程---Mutex实现Service线程和work线程
- Windows多线程编程(4)同步对象——Mutex对象
- 线程、同步与锁——Mutex想说爱你不容易
- 线程、同步与锁——Mutex想说爱你不容易
- C#线程同步——lock,Monitor,Mutex
- 线程、同步与锁——Mutex想说爱你不容易
- Linux线程同步之——互斥量(Mutex)
- 多线程 ——pthread
- 寄存器基础
- 清除浮动的几种方法
- hdu5927Auxiliary Set
- Ajax反正现在我没怎么看懂
- Lock的await/singal 和 Object的wait/notify 的区别
- Pthread线程 —— 多线程同步 互斥锁(mutex)
- 网络流
- Normal Map中的值, Tangent Space, 求算 Tangent 与 Binormal 与 TBN Matrix
- css选择器总结
- 全国信息学奥林匹克联赛(NOIP2016 )复赛模拟(二)
- hdu5925 Coconuts 离散化 dfs搜索 TWT Tokyo Olympic 1combo-1
- unity3d--CharacterController
- Pthread 线程 —— 多线程同步 条件变量(cond)
- Test running failed: Unable to find instrumentation info for: ComponentInfo