没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
最近关注了几个其他线程间同步的方法,之前用的比较简单了,使用全局变量置标志,在线程中根据标志
实现相应操作,搜索了一下,还有些其他方法,自己做了 Demo,在此总结一下:
1.临界区(Critical Section):适合一个进程内的多线程访问公共区域或代码段时使用。
API:
VOID EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection); //进入临界区
VOID LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection); //离开临界区
某 一 线 程 调 用 EnterCriticalSection 函 数 进 入 临 界 区 后 , 必 须 保 证 最 后 可 以 调 用
LeaveCriticalSection,否则公共区域无法释放,并被其它线程访问。
在 MFC 中封装了 CCriticalSection 类,该类提供进入临界区和离开临界区的函数 Lock()和
Unlock()
Ex:
CCriticalSection cs; //临界区对象
void ThreadFunction()
{
cs.Lock();
// 代码
cs.Unlock();
} //end ThreadFunction
2.互斥量 (Mutex):适合不同进程内多线程访问公共区域或代码段时使用,与临界区相似。
HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes,BOOL
bInitialOwner,LPCTSTR lpName);
//创建一个互斥量,返回值为这个互斥量的句柄。参数 bInitialOwner 表示是否由调用此函数
的进程拥有此互斥量
API:‚
HANDLE OpenMutex(DWORD dwDesiredAccess,BOOL hInheritHandle,LPCTSTR
lpName);//打开一个已创建的互斥量
BOOL ReleaseMutex(HANDLE hMutex); //释放
MFC 中封装了 CMutex 类,同样的函数 Lock()和 Unlock()
3.事件(Event):通过线程间触发事件实现同步互斥
API:‚‚
HANDLE CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes,BOOL
bManualReset,BOOL bInitialState,LPCTSTR lpName); //创建一个事件,返回值为事件句柄
参数 bManualReset 表示是否通过手动重设事件,参数为 TRUE,则需要调用 ResetEvent 重设
事件,否则为自动重设
HANDLE OpenEvent(DWORD dwDesizedAccess,BOOL bInheritHandle,LPCTSTR
lpName);//打开事件
在 MFC 中 封 装 了 CEvent 类 , 包 括 SetEvent() 触 发 事 件 、 PulseEvent 暂 停 事 件 、
ResetEvent()重设事件及 Unlock()释放事件句柄
4.信号量(Semaphore):与临界区和互斥量不同,可以实现多个线程同时访问公共区域数据 ,
原理与操作系统中 PV 操作类似,先设置一个访问公共区域的线程最大连接数,每有一个线程
访问共享区资源数就减一,直到资源数小于等于零。
API:
HANDLE CreateSemaphore(LPSECURITY_ATTRIBUTES,LONG lInitialCount,LONG
lMaxmemCount,LPCTSTR lpName);
//创建信号量,返回句柄,参数 lInitialCount 为信号量资源初始数基数,参数 lMaxmemCount
为该信号量的最大数
HANDLE OpenSemaphore(DWORD dwDesiredAccess,BOOL hInheriHandle,LPCTSTR
lpName);//打开信号量
BOOL ReleaseSemaphore(HANDLE bSemaphore,LONG lReleaseCount,LPLONG
lpPreviousCount); //释放信号量
在 MFC 中封装了 CSemaphore 类,声明该类的对象后使用 API:WaitForSingleObject()函数实
现等待访问资源,使用 ReleaseSemaphore 函数释放资源,函数参数中需串入信号量对象句柄。
总结:上述 4 个实现线程同步互斥的类均派生自虚基类 CSyncObject,除临界区外其它 3 中方
式均可用于多进程间线程同步互斥。
另:线程触发自定义事件
可 使 用 API 函 数 PostThreadMessage() 函 数 , 或 创 建 CWinThread 对 象 , 调 用 该 类 的
PostThreadMessage()
互斥锁是一种通过简单的加锁的方法来控制对共享资源的存取,用于解决线程间资源访问的唯一性问题。
互斥锁有上锁和解锁两种状态,在同一时刻只能有一个线程掌握某个互斥的锁,拥有上锁状态的线程可以
对共享资源进行操作。若其他线程希望对一个已经上了锁的互斥锁上锁,则该线程会被挂起,直到上锁的
线程释放掉互斥锁为止。
操作互斥锁的基本函数有:1.pthread_mutex_init ——互斥锁初始化;2.pthread_mutex_lock——互斥锁
上锁(阻塞版); 3.pthread_mutex_trtylock——互斥锁上锁(非阻塞版); 4.pthread_mutex_unlock
——互斥锁解锁;5.pthread_mutex_destory——消除互斥锁。
线程互斥锁的数据类型是 pthread_mutex_t,在使用前,要对其进行初始化,有以下两种方法:
静态初始化:可以把常量 PTHREAD_MUTEX_INITIALIZER 赋给静态分配的互斥锁变量;
动 态 初 始 化 : 在 申 请 内 存 之 后 , 通 过 pthread_mutex_init 进 行 初 始 化 , 在 释 放 内 存 前 需 要 调 用
pthread_mutex_destroy。
互斥锁的一个明显缺点是它只有两种状态:锁定和非锁定。而条件变量通过允许线程阻塞和等待另一个线
程放松信号的方法弥补了互斥锁的不足,它常和互斥锁一块使用。使用时,条件变量被用来阻塞一个线程 ,
当条件不满足时,线程往往解开相应的互斥锁并等待条件发生变化。一旦其他的某个线程改变了条件变量 ,
它将通知相应的条件变量唤醒一个或多个正在被此条件阻塞的线程。这些线程将重新锁定互斥锁并重新测
试条件是否满足。条件变量上的基本操作有两个。1.触发条件:当条件变为 true 时;2.等待条件:挂起线
程直到其他线程触发条件。条件变量的数据类型是 pthreead_cond_t,在使用前也需要初始化
一、什么是互斥锁
另一种在多线程程序中同步访问手段是使用互斥量。程序员给某个对象加
上一把“锁”,每次只允许一个线程去访问它。如果想对代码关键部分的访问进
行控制,你必须在进入这段代码之前锁定一把互斥量,在完成操作之后再打开
它。
互斥量函数有
pthread_mutex_init 初始化一个互斥量
pthread_mutex_lock 给一个互斥量加锁
pthread_mutex_trylock 加锁,如果失败不阻塞
pthread_mutex_unlock 解锁
可以通过使用 pthread 的互斥接口保护数据,确保同一时间只有一个线程
访问数据。互斥量从本质上说是一把锁,在访问共享资源前对互斥量进行加锁,
在访问完成后释放互斥量上的锁。对互斥量进行加锁以后,任何其他试图再次
对互斥量加锁的线程将会被阻塞直到当前线程释放该互斥锁。如果释放互斥锁
时有多个线程阻塞,所以在该互斥锁上的阻塞线程都会变成可进行状态,第一
个变成运行状态的线程可以对互斥量加锁,其他线程在次被阻塞,等待下次运
行状态。
互斥量用 pthread_mutex_t 数据类型来表示,在使用互斥量以前,必须首
先对它进行初始化,可以把它置为常量 PTHREAD_MUTEX_INITIALIZER(只对
静态分配的互斥量),也可以通过调用 pthread_mutex_init 函数进行初始化,如
果动态地分配互斥量,那么释放内存前需要调用 pthread_mutex_destroy.
二、初始化/回收互斥锁
1.
名称::
pthread_mutexattr_init
功能:
初始化互斥锁。
头文件:
#include <pthread.h>
函数原形:
int pthread_mutex_init(pthread_mutex_t * mutex,
const pthread_mutex_t *attr);
参数:
mutex 互斥量
attr 互斥锁属性
返回值:
若成功则返回 0,否则返回错误编号。
mutex 是我们要锁住的互斥量,attr 是互斥锁的属性,可用相应的函数修改,
我们在下章介绍,要用默认的属性初始化互斥量,只需把 attr 设置为 NULL。
对互斥量进行加锁,需要调用 pthread_mutex_lock,如果互斥量已经上锁,调
用线程阻塞直至互斥量解锁。对互斥量解锁,需要调用 pthread_mutex_unlock.
如果线程不希望被阻塞,他可以使用 pthread_mutex_trylock 尝试对互斥量
进行加锁。如果调用 pthread_mutex_trylock 时互斥量处于未锁住状态,那么
pthread_mutex_trylock 将锁住互斥量,否则就会失败,不能锁住互斥量,而返
回 EBUSY。
下面试例子可以证明对互斥量加锁的必要性:
我们先来看不加锁的程序。
#inlcude <stdio.h>
#include <pthread.h>
#inlcude <stdio.h>
#include <unistd.h>
viid *thread_function(void *arg);
int run_now=1; /*用 run_now 代表共享资源*/
int main()
{
int print_count1=0; /*用于控制循环*/
prhread_t a_thread;
if(pthread_create(&a_thread,NULL,thread_function,NULL)!=0) /*创建一个进
程*/
{
perror(“Thread createion failed”);
exit(1);
}
while(print_count1++<5)
{
if(run_now==1) /主线程:如果 run_now 为 1 就把它修改为 2*/
{
printf(“main thread is run\n”);
run_now=2;
}
else
{
printf(“main thread is sleep\n”);
sleep(1);
}
}
pthread_join(a_thread,NULL); /*等待子线程结束*/
exit(0);
}
void *thread_function(void *arg)
剩余20页未读,继续阅读
资源评论
- fliegenderx2012-11-13很全,就是编排有些乱。
miaogudu
- 粉丝: 1
- 资源: 4
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功