线程间实现同步互斥的方法.doc_第1页
线程间实现同步互斥的方法.doc_第2页
线程间实现同步互斥的方法.doc_第3页
线程间实现同步互斥的方法.doc_第4页
线程间实现同步互斥的方法.doc_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

最近关注了几个其他线程间同步的方法,之前用的比较简单了,使用全局变量置标志,在线程中根据标志实现相应操作,搜索了一下,还有些其他方法,自己做了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 ThreadFunction2.互斥量 (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 函数原形: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 #include #inlcude #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) if(run_now=2) /子线程:如果run_now为1就把它修改为1*/ printf(“function thread is runn”); run_now=1; else printf(“function thread is sleepn”); sleep(1); pthread_exit(NULL);运行上面程序的运行结果为:function thread is sleepmain thread is runmain thread is sleepmain thread is sleepfunction thread is run function thread is sleepmain thread is runmain thread is sleepfunction thread is runfunction thread is sleep我们可以看到main线程和function线程是交替运行的。它们都可以对run_now进行操作。下面是加锁的程序。#inlcude #include #inlcude viid *thread_function(void *arg);int run_now=1; /*用run_now代表共享资源*/ pthread_mutex_t work_mutex; /*定义互斥量*/int main()int res;int print_count1=0;prhread_t a_thread;if(pthread_mutex_init(&work_mutex,NULL)!=0) /*初始化互斥量*/ perror(“Mutex init faied”); exit(1);if(pthread_create(&a_thread,NULL,thread_function,NULL)!=0) /*创建新线程*/ perror(“Thread createion failed”); exit(1);if(pthread_mutex_lock(&work_mutex)!=0) /*对互斥量加锁*/ preeor(“Lock failed”); exit(1);else printf(“main lockn”);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); if(pthread_mutex_unlock(&work_mutex)!=0) /*对互斥量解锁*/ preeor(“unlock failed”); exit(1);else printf(“main unlockn”);pthread_mutex_destroy(&work_mutex); /*收回互斥量资源*/pthread_join(a_thread,NULL); /*等待子线程结束*/exit(0);void *thread_function(void *arg)int print_count2=0;sleep(1);if(pthread_mutex_lock(&work_mutex)!=0) perror(“Lock failed”

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论