线程同步:递归锁、非递归锁
来源:互联网 发布:数据库系统实现 4.2.1 编辑:程序博客网 时间:2024/06/05 02:30
一、简介
1.1 进程/线程同步方法
常见的进程/线程同步方法有互斥锁(或称互斥量Mutex)、读写锁(rdlock)、条件变量(cond)、信号量(Semophore)等。
在windows系统中,临界区(Critical Section)和事件对象(Event)也是常用的同步方法。
1.2 递归锁/非递归锁
Mutex可以分为递归锁(recursive mutex)和非递归锁(non-recursive mutex)。 递归锁也叫可重入锁(reentrant mutex),非递归锁也叫不可重入锁(non-reentrant mutex)。
二者唯一的区别是:
同一个线程可以多次获取同一个递归锁,不会产生死锁。
如果一个线程多次获取同一个非递归锁,则会产生死锁。
Windows下的Mutex和Critical Section是可递归的。
Linux下的pthread_mutex_t锁是默认是非递归的。可以通过设置PTHREAD_MUTEX_RECURSIVE属性,将pthread_mutex_t锁设置为递归锁。
二、代码
2.1 Critical Section递归锁
#include <Windows.h>#include <iostream>#include <string>int counter = 0;CRITICAL_SECTION g_cs;void doit(void* arg){int i, val;for (i=0; i<5000; i++){EnterCriticalSection(&g_cs);EnterCriticalSection(&g_cs);val = counter;printf("thread %d : %d\n", int(arg), val+1);counter = val + 1;LeaveCriticalSection(&g_cs);LeaveCriticalSection(&g_cs);}}int main(int argc, char*argv[]){InitializeCriticalSection(&g_cs);HANDLE hThread1 = CreateThread(NULL,0, (LPTHREAD_START_ROUTINE)doit, (void*)1, 0, NULL);HANDLE hTrehad2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)doit, (void*)2, 0, NULL);WaitForSingleObject(hThread1, INFINITE);WaitForSingleObject(hTrehad2, INFINITE);DeleteCriticalSection(&g_cs);return 0;}
结果:加1次锁和2次锁,均可以正确的输出1~10000。
2.2 pthread_mutex_t非递归锁
#include <stdio.h>#include <stdlib.h>#include <pthread.h>int counter = 0;pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;void* doit(void*){ int i, val; for (i=0; i<5000; i++) { pthread_mutex_lock(&g_mutex); pthread_mutex_lock(&g_mutex); val = counter; printf("%x: %d\n", pthread_self(), val+1); counter = val + 1; pthread_mutex_unlock(&g_mutex); pthread_mutex_unlock(&g_mutex); }}int main(int argc, char*argv[]){ pthread_t tid1, tid2; pthread_create(&tid1, NULL, doit, NULL); pthread_create(&tid2, NULL, doit, NULL); pthread_join(tid1, NULL); pthread_join(tid2, NULL); return 0;}
结果:加1次锁,可以正确的输出1~10000;加2次锁,死锁,不输出任何信息。
2.3 pthread_mutex_t递归锁(PTHREAD_MUTEX_RECURSIVE)
#include <stdio.h>#include <stdlib.h>#include <pthread.h>int counter = 0;pthread_mutex_t g_mutex;// = PTHREAD_MUTEX_INITIALIZER;void* doit(void*){ int i, val; for (i=0; i<5000; i++) { pthread_mutex_lock(&g_mutex); pthread_mutex_lock(&g_mutex); val = counter; printf("%x: %d\n", pthread_self(), val+1); counter = val + 1; pthread_mutex_unlock(&g_mutex); pthread_mutex_unlock(&g_mutex); }}int main(int argc, char*argv[]){ //create recursive attribute pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); //set recursive attribute pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&g_mutex, &attr); pthread_t tid1, tid2; pthread_create(&tid1, NULL, doit, NULL); pthread_create(&tid2, NULL, doit, NULL); pthread_join(tid1, NULL); pthread_join(tid2, NULL); pthread_mutex_destroy(&g_mutex); //destroy recursive attribute pthread_mutexattr_destroy(&attr); return 0;}结果:加1次锁和2次锁,均可以正确的输出1~10000。
参考资料:http://blog.chinaunix.net/uid-26983585-id-3316794.html
- 线程同步:递归锁、非递归锁
- 线程同步--递归锁 非递归锁
- 线程同步----递归锁
- 线程同步之利器(1)——可递归锁与非递归锁
- 线程同步之利器(1)——可递归锁与非递归锁
- 线程同步之利器(1)——可递归锁与非递归锁
- 递归锁与非递归锁
- 可递归锁与非递归锁
- 可递归锁与非递归锁
- 可递归锁与非递归锁
- 可递归锁与非递归锁
- 可递归锁与非递归锁
- 可递归锁与非递归锁
- 递归锁和非递归锁
- 可递归锁与非递归锁
- Python3之多线程GIL、同步锁、信号量、死锁与递归锁、线程Queue、Event、定时器
- boost递归锁和非递归锁区别
- 递归与非递归
- http://www.duwenzhang.com/plus/view.php?aid=278609
- Do YOU know Resque?
- VS开发工具文件模板
- 【Java并发编程实践】— 线程安全
- zTree 的异步加载加载实现--jfinal
- 线程同步:递归锁、非递归锁
- 网页中id与name的区别
- 控制器从视图接收参数--第二篇
- 使用python的logging模块
- android中通过Http访问图片工具类的实现
- java与oracle的连接
- XBMC源代码简析 5:视频播放器(dvdplayer)-解复用器(以ffmpeg为例)
- 面向对象技术
- SQL如何插入字段说明