线程间实现同步互斥的方法.doc

上传人:鲁** 文档编号:557605125 上传时间:2024-01-22 格式:DOC 页数:11 大小:56.01KB
返回 下载 相关 举报
线程间实现同步互斥的方法.doc_第1页
第1页 / 共11页
线程间实现同步互斥的方法.doc_第2页
第2页 / 共11页
线程间实现同步互斥的方法.doc_第3页
第3页 / 共11页
线程间实现同步互斥的方法.doc_第4页
第4页 / 共11页
线程间实现同步互斥的方法.doc_第5页
第5页 / 共11页
点击查看更多>>
资源描述

《线程间实现同步互斥的方法.doc》由会员分享,可在线阅读,更多相关《线程间实现同步互斥的方法.doc(11页珍藏版)》请在金锄头文库上搜索。

1、最近关注了几个其他线程间同步的方法,之前用的比较简单了,使用全局变量置标志,在线程中根据标志实现相应操作,搜索了一下,还有些其他方法,自己做了Demo,在此总结一下:1.临界区(Critical Section):适合一个进程内的多线程访问公共区域或代码段时使用。 API: VOID EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection); /进入临界区 VOID LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection); /离开临界区 某一线程调用EnterCritica

2、lSection函数进入临界区后,必须保证最后可以调用LeaveCriticalSection,否则公共区域无法释放,并被其它线程访问。在MFC中封装了CCriticalSection类,该类提供进入临界区和离开临界区的函数Lock()和Unlock() Ex:CCriticalSection cs; /临界区对象 void ThreadFunction() cs.Lock();/ 代码 cs.Unlock(); /end ThreadFunction2.互斥量 (Mutex):适合不同进程内多线程访问公共区域或代码段时使用,与临界区相似。 HANDLE CreateMutex(LPSECUR

3、ITY_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.事件(Eve

4、nt):通过线程间触发事件实现同步互斥API: HANDLE CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes,BOOL bManualReset,BOOL bInitialState,LPCTSTR lpName); /创建一个事件,返回值为事件句柄 参数bManualReset表示是否通过手动重设事件,参数为TRUE,则需要调用ResetEvent重设事件,否则为自动重设HANDLE OpenEvent(DWORD dwDesizedAccess,BOOL bInheritHandle,LPCTSTR lpName);/打开事件在MFC

5、中封装了CEvent类,包括SetEvent() 触发事件、PulseEvent 暂停事件、ResetEvent()重设事件及Unlock()释放事件句柄4.信号量(Semaphore):与临界区和互斥量不同,可以实现多个线程同时访问公共区域数据,原理与操作系统中PV操作类似,先设置一个访问公共区域的线程最大连接数,每有一个线程访问共享区资源数就减一,直到资源数小于等于零。API:HANDLE CreateSemaphore(LPSECURITY_ATTRIBUTES,LONG lInitialCount,LONG lMaxmemCount,LPCTSTR lpName);/创建信号量,返回句

6、柄,参数lInitialCount为信号量资源初始数基数,参数lMaxmemCount为该信号量的最大数HANDLE OpenSemaphore(DWORD dwDesiredAccess,BOOL hInheriHandle,LPCTSTR lpName);/打开信号量BOOL ReleaseSemaphore(HANDLE bSemaphore,LONG lReleaseCount,LPLONG lpPreviousCount); /释放信号量在MFC中封装了CSemaphore类,声明该类的对象后使用API:WaitForSingleObject()函数实现等待访问资源,使用Releas

7、eSemaphore函数释放资源,函数参数中需串入信号量对象句柄。总结:上述4个实现线程同步互斥的类均派生自虚基类CSyncObject,除临界区外其它3中方式均可用于多进程间线程同步互斥。另:线程触发自定义事件可使用API函数PostThreadMessage()函数,或创建CWinThread对象,调用该类的PostThreadMessage()互斥锁是一种通过简单的加锁的方法来控制对共享资源的存取,用于解决线程间资源访问的唯一性问题。互斥锁有上锁和解锁两种状态,在同一时刻只能有一个线程掌握某个互斥的锁,拥有上锁状态的线程可以对共享资源进行操作。若其他线程希望对一个已经上了锁的互斥锁上锁,

8、则该线程会被挂起,直到上锁的线程释放掉互斥锁为止。操作互斥锁的基本函数有: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赋给静态分配的互斥锁变量;动态初始化:在申请内存之后

9、,通过pthread_mutex_init进行初始化,在释放内存前需要调用pthread_mutex_destroy。互斥锁的一个明显缺点是它只有两种状态:锁定和非锁定。而条件变量通过允许线程阻塞和等待另一个线程放松信号的方法弥补了互斥锁的不足,它常和互斥锁一块使用。使用时,条件变量被用来阻塞一个线程,当条件不满足时,线程往往解开相应的互斥锁并等待条件发生变化。一旦其他的某个线程改变了条件变量,它将通知相应的条件变量唤醒一个或多个正在被此条件阻塞的线程。这些线程将重新锁定互斥锁并重新测试条件是否满足。条件变量上的基本操作有两个。1.触发条件:当条件变为true时;2.等待条件:挂起线程直到其他

10、线程触发条件。条件变量的数据类型是pthreead_cond_t,在使用前也需要初始化一、什么是互斥锁 另一种在多线程程序中同步访问手段是使用互斥量。程序员给某个对象加上一把“锁”,每次只允许一个线程去访问它。如果想对代码关键部分的访问进行控制,你必须在进入这段代码之前锁定一把互斥量,在完成操作之后再打开它。 互斥量函数有 pthread_mutex_init 初始化一个互斥量 pthread_mutex_lock 给一个互斥量加锁 pthread_mutex_trylock 加锁,如果失败不阻塞 pthread_mutex_unlock 解锁 可以通过使用pthread的互斥接口保护数据,确

11、保同一时间只有一个线程访问数据。互斥量从本质上说是一把锁,在访问共享资源前对互斥量进行加锁,在访问完成后释放互斥量上的锁。对互斥量进行加锁以后,任何其他试图再次对互斥量加锁的线程将会被阻塞直到当前线程释放该互斥锁。如果释放互斥锁时有多个线程阻塞,所以在该互斥锁上的阻塞线程都会变成可进行状态,第一个变成运行状态的线程可以对互斥量加锁,其他线程在次被阻塞,等待下次运行状态。 互斥量用pthread_mutex_t数据类型来表示,在使用互斥量以前,必须首先对它进行初始化,可以把它置为常量PTHREAD_MUTEX_INITIALIZER(只对静态分配的互斥量),也可以通过调用pthread_mute

12、x_init函数进行初始化,如果动态地分配互斥量,那么释放内存前需要调用pthread_mutex_destroy.二、初始化/回收互斥锁1名称::pthread_mutexattr_init功能:初始化互斥锁。头文件:#include 函数原形:int pthread_mutex_init(pthread_mutex_t * mutex,const pthread_mutex_t *attr);参数:mutex 互斥量attr 互斥锁属性返回值:若成功则返回0,否则返回错误编号。mutex是我们要锁住的互斥量,attr是互斥锁的属性,可用相应的函数修改,我们在下章介绍,要用默认的属性初始化互

13、斥量,只需把attr设置为NULL。对互斥量进行加锁,需要调用pthread_mutex_lock,如果互斥量已经上锁,调用线程阻塞直至互斥量解锁。对互斥量解锁,需要调用pthread_mutex_unlock. 如果线程不希望被阻塞,他可以使用pthread_mutex_trylock尝试对互斥量进行加锁。如果调用pthread_mutex_trylock时互斥量处于未锁住状态,那么pthread_mutex_trylock将锁住互斥量,否则就会失败,不能锁住互斥量,而返回EBUSY。下面试例子可以证明对互斥量加锁的必要性:我们先来看不加锁的程序。#inlcude #include #inl

14、cude #include 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 runn”); run_now=2; else printf(“main thread is sleepn”); sleep(1); pthread_join(a_thread,NULL); /*等待子线程结束*/exit(0);void *thread_function(void *arg)int print_count2=0;while(print_count2+5) i

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 生活休闲 > 科普知识

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号