2023年6月22日发(作者:)
对于EnterCriticalSection和LeaveCriticalSection的理解和⽤法线程锁的概念函数EnterCriticalSection和LeaveCriticalSection的⽤法注:使⽤结构CRITICAL_SECTION 需加⼊头⽂件#include “afxmt.h”定义⼀个全局的锁 CRITICAL_SECTION的实例和⼀个静态全局变量1. CRITICAL_SECTIONcs;// 临界区的声明2. static intn_AddValue = 0;//定义⼀个静态的全部变量n_AddValue创建两个线程函数,代码实现如下:1. //第⼀个线程2. UINT FirstThread(LPVOIDlParam)3. {4. EnterCriticalSection(&cs);//进⼊临界区,对需要保护的资源进⾏操作5. for(int i =0; i<10;i++){
6. n_AddValue ++;7. cout <<"n_AddValue in FirstThread is"< 8. 9. }10. LeaveCriticalSection(&cs);//离开临界区 11. return 0;12. 13. }14. 15. //第⼆个线程16. UINT SecondThread(LPVOIDlParam)17. {18. EnterCriticalSection(&cs);//进⼊临界区19. for(int i =0; i<10;i++){ 20. n_AddValue ++; 21. cout <<"n_AddValue in SecondThread is"< 22. 23. }24. LeaveCriticalSection(&cs);//离开临界区25. 26. return 0;27. 28. }在主函数添加以下代码1. int_tmain(intargc, TCHAR*argv[],TCHAR* envp[])2. {3. int nRetCode =0;4. 5. // 初始化 MFC 并在失败时显⽰错误6. if (!AfxWinInit(::GetModuleHandle(NULL),NULL, ::GetCommandLine(),0))7. {8. // TODO: 更改错误代码以符合您的需要9. _tprintf(_T("错误: MFC 初始化失败/n"));10. nRetCode =1;11. }12. else13. {14. 15. InitializeCriticalSection(&cs);//初始化临界区16. 17. 18. CWinThread *pFirstThread,*pSecondThread;//存储函数AfxBeginThread返回的CWinThread指针19. 20. 21. pFirstThread =AfxBeginThread(FirstThread,LPVOID(NULL));//启动第⼀个线程22. pSecondThread =AfxBeginThread(SecondThread,LPVOID(NULL));//启动第⼆个线程23. 24. HANDLE hThreadHandle[2];//25. hThreadHandle[0] =pFirstThread->m_hThread;26. hThreadHandle[1] =pSecondThread->m_hThread;27. 28. //等待线程返回29. WaitForMultipleObjects(2,hThreadHandle,TRUE,INFINITE); 30. }31. 32. return nRetCode;33. }输出:n_AddValue in FirstThread is 1n_AddValue in FirstThread is 2n_AddValue in FirstThread is 3n_AddValue in FirstThread is 4n_AddValue in FirstThread is 5n_AddValue in FirstThread is 6n_AddValue in FirstThread is 7n_AddValue in FirstThread is 8n_AddValue in FirstThread is 9n_AddValue in FirstThread is 10n_AddValue in SecondThread is 11n_AddValue in SecondThread is 12n_AddValue in SecondThread is 13n_AddValue in SecondThread is 14n_AddValue in SecondThread is 15n_AddValue in SecondThread is 16n_AddValue in SecondThread is 17n_AddValue in SecondThread is 18n_AddValue in SecondThread is 19n_AddValue in SecondThread is 20如果把两个线程函数中的EnterCriticalSection和LeaveCriticalSection位置移到for循环中去,线程的执⾏顺序将会改变输出也就跟着改变,如:1. //第⼀个线程2. UINT FirstThread(LPVOIDlParam)3. {4. 5. for(int i =0; i<10;i++){6. EnterCriticalSection(&cs);///进⼊临界区,临界区移到for循环内部⾥7. n_AddValue ++;8. cout <<"n_AddValue in FirstThread is"< 9. LeaveCriticalSection(&cs);//离开临界区10. } 11. return 0;12. }13. 14. //第⼆个线程15. UINT SecondThread(LPVOIDlParam)16. {17. 18. for(int i =0; i<10;i++){ 19. EnterCriticalSection(&cs);//进⼊临界区20. n_AddValue ++; 21. cout <<"n_AddValue in SecondThread is"< 也正由于CRITICAL_SECTION是这样发挥作⽤的,所以,必须把每⼀个线程中访问共享资源的语句都放在EnterCritialSection和LeaveCriticalSection之间。这是初学者很容易忽略的地⽅。当然,上⾯说的都是对于同⼀个CRITICAL_SECTION⽽⾔的。 如果⽤到两个CRITICAL_SECTION,⽐如说: 第⼀个线程已经执⾏了EnterCriticalSection(&cs)并且还没有执⾏LeaveCriticalSection(&cs),这时另⼀个线程想要执⾏EnterCriticalSection(&cs2),这种情况是可以的(除⾮cs2已经被第三个线程抢先占⽤了)。 这也就是多个CRITICAL_SECTION实现同步的思想。
发布者:admin,转转请注明出处:http://www.yc00.com/news/1687427265a9248.html
评论列表(0条)