大家好,又见面了,我是你们的朋友全栈君。
线程锁的概念函数EnterCriticalSection和LeaveCriticalSection的用法
注:使用结构CRITICAL_SECTION 需加入头文件#include “afxmt.h”
定义一个全局的锁 CRITICAL_SECTION的实例 和一个静态全局变量
- CRITICAL_SECTIONcs;// 临界区的声明
- static intn_AddValue = 0;//定义一个静态的全部变量n_AddValue
创建两个线程函数,代码实现如下:
- //第一个线程
- UINT FirstThread(LPVOIDlParam)
- {
- EnterCriticalSection(&cs);//进入临界区,对需要保护的资源进行操作
- for(int i =0; i<10;i ){
- n_AddValue ;
- cout <<“n_AddValue in FirstThread is“<<n_AddValue <<endl;
- }
- LeaveCriticalSection(&cs);//离开临界区
- return 0;
- }
- //第二个线程
- UINT SecondThread(LPVOIDlParam)
- {
- EnterCriticalSection(&cs);//进入临界区
- for(int i =0; i<10;i ){
- n_AddValue ;
- cout <<“n_AddValue in SecondThread is“<<n_AddValue <<endl;
- }
- LeaveCriticalSection(&cs);//离开临界区
- return 0;
- }
在主函数添加以下代码
- int_tmain(intargc, TCHAR*argv[],TCHAR* envp[])
- {
- int nRetCode =0;
- // 初始化 MFC 并在失败时显示错误
- if (!AfxWinInit(::GetModuleHandle(NULL),NULL, ::GetCommandLine(),0))
- {
- // TODO: 更改错误代码以符合您的需要
- _tprintf(_T(“错误: MFC 初始化失败/n“));
- nRetCode =1;
- }
- else
- {
- InitializeCriticalSection(&cs);//初始化临界区
- CWinThread *pFirstThread,*pSecondThread;//存储函数AfxBeginThread返回的CWinThread指针
- pFirstThread =AfxBeginThread(FirstThread,LPVOID(NULL));//启动第一个线程
- pSecondThread =AfxBeginThread(SecondThread,LPVOID(NULL));//启动第二个线程
- HANDLE hThreadHandle[2];//
- hThreadHandle[0] =pFirstThread->m_hThread;
- hThreadHandle[1] =pSecondThread->m_hThread;
- //等待线程返回
- WaitForMultipleObjects(2,hThreadHandle,TRUE,INFINITE);
- }
- return nRetCode;
- }
输出:
n_AddValue in FirstThread is 1 n_AddValue in FirstThread is 2 n_AddValue in FirstThread is 3 n_AddValue in FirstThread is 4 n_AddValue in FirstThread is 5 n_AddValue in FirstThread is 6 n_AddValue in FirstThread is 7 n_AddValue in FirstThread is 8 n_AddValue in FirstThread is 9 n_AddValue in FirstThread is 10 n_AddValue in SecondThread is 11 n_AddValue in SecondThread is 12 n_AddValue in SecondThread is 13 n_AddValue in SecondThread is 14 n_AddValue in SecondThread is 15 n_AddValue in SecondThread is 16 n_AddValue in SecondThread is 17 n_AddValue in SecondThread is 18 n_AddValue in SecondThread is 19 n_AddValue in SecondThread is 20
如果把两个线程函数中的EnterCriticalSection和LeaveCriticalSection位置移到for循环中去,线程的执行顺序将会改变 输出也就跟着改变,如:
- //第一个线程
- UINT FirstThread(LPVOIDlParam)
- {
- for(int i =0; i<10;i ){
- EnterCriticalSection(&cs);///进入临界区,临界区移到for循环内部里
- n_AddValue ;
- cout <<“n_AddValue in FirstThread is“<<n_AddValue <<endl;
- LeaveCriticalSection(&cs);//离开临界区
- }
- return 0;
- }
- //第二个线程
- UINT SecondThread(LPVOIDlParam)
- {
- for(int i =0; i<10;i ){
- EnterCriticalSection(&cs);//进入临界区
- n_AddValue ;
- cout <<“n_AddValue in SecondThread is“<<n_AddValue <<endl;
- LeaveCriticalSection(&cs); //离开临界区
- }
- return 0;
- }
其他代码不变,输出的结果如下:
n_AddValue in FirstThread is 1 n_AddValue in SecondThread is 2 n_AddValue in FirstThread is 3 n_AddValue in SecondThread is 4 n_AddValue in FirstThread is 5 n_AddValue in SecondThread is 6 n_AddValue in FirstThread is 7 n_AddValue in SecondThread is 8 n_AddValue in FirstThread is 9 n_AddValue in SecondThread is 10 n_AddValue in FirstThread is 11 n_AddValue in SecondThread is 12 n_AddValue in FirstThread is 13 n_AddValue in SecondThread is 14 n_AddValue in FirstThread is 15 n_AddValue in SecondThread is 16 n_AddValue in FirstThread is 17 n_AddValue in SecondThread is 18 n_AddValue in FirstThread is 19 n_AddValue in SecondThread is 20 另外,很多人对CRITICAL_SECTION的理解是错误的,认为CRITICAL_SECTION是锁定了资源,其实,CRITICAL_SECTION是不能够“锁定”资源的,它能够完成的功能,是同步不同线程的代码段。简单说,当一个线程执行了EnterCritialSection之后,cs里面的信息便被修改了,以指明哪一个线程占用了它。而此时,并没有任何资源被“锁定”。不管什么资源,其它线程都还是可以访问的(当然,执行的结果可能是错误的)。只不过,在这个线程尚未执行LeaveCriticalSection之前,其它线程碰到EnterCritialSection语句的话,就会处于等待状态,相当于线程被挂起了。 这种情况下,就起到了保护共享资源的作用。 也正由于CRITICAL_SECTION是这样发挥作用的,所以,必须把每一个线程中访问共享资源的语句都放在EnterCritialSection和LeaveCriticalSection之间。这是初学者很容易忽略的地方。 当然,上面说的都是对于同一个CRITICAL_SECTION而言的。 如果用到两个CRITICAL_SECTION,比如说: 第一个线程已经执行了EnterCriticalSection(&cs)并且还没有执行LeaveCriticalSection(&cs),这时另一个线程想要执行EnterCriticalSection(&cs2),这种情况是可以的(除非cs2已经被第三个线程抢先占用了)。 这也就是多个CRITICAL_SECTION实现同步的思想。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/191492.html原文链接:https://javaforall.cn