initializecriticalsection?declspec dllimport?getprivateprofi

电脑杂谈  发布时间:2016-09-12 05:00:38  来源:网络整理

你是否正在寻找关于initializecriticalsection的内容?让我把最全的东西奉献给你:

当多个线程同时使用相同的资源时,由于是并发执行,不能保证先后顺序.所以假如时一个公共变量被几个线程同时使用会造成该变量的混乱.

下面来举个简单例子.

假如有一个字符数组变量

char g_charArray[4];

CString szResult;

AfxBeginThread(FunOne,NULL); //FunOne给数组赋全为S

AfxBeginThread(FunTwo,NULL); //FunTwo也给数组赋全为B

AfxBeginThread(GetResult,NULL); //得到数组的,本来期望的为最后一次赋的BBBB.但实际结果是不确定的,可能是SBSB,SSBB或者其它

UINT FunOne(LPVOID pParam){ //给数组赋

for(int i =0; i < 4; i){

g_charArray[i] = 'S';

Sleep(10);

}

return 0;

}

UINT FunTwo(LPVOID pParam){//得到数组

for(int i =0; i < 4; i){

g_charArray[i] = 'B';

Sleep(10);

}

return 0;

}

UINT GetResult(LPVOID pParam){//给数组赋

szResult = CString(g_charArray);

return 0;

}

Win32 API中临界区(Critical Section)

为了使公共变量不会被毫无秩序,混乱的更改.我们希望一个线程使用这个变量时其他线程就不能使用,只能等别的线程用完了才用.

于是出现了临界区这说法,相当于把使用到的变量的内存看作一块区域,当某个线程使用时就进入该区域,使用完了离开.当有一个线程进入该区域时其他线程就只能在外面等.临界区的使用如下.

临界区只能用于同一个进程内的线程同步.如果想要多个进程间的线程同步就不能用它了.

CRITICAL_SECTION g_criSection //定义临界区变量

void MainTestFun{

initializecriticalsection(&g_criSection); //使用前必须初始化

char g_charArray[4];

CString szResult;

AfxBeginThread(FunOne,NULL);

AfxBeginThread(FunTwo,NULL);

AfxBeginThread(GetResult,); //此时得到的总是BBBB或者SSSS,哪一个线程拥有临界区不确定.只能保证某一个时间只能有一个线程拥有

//DeleteCriticalSection(&g_criSection); 使用完了临界区就要删除掉,但是在这里这样使用可能会出错.因为必须保证在删除时这个临界区没有再被使用了.所以如果一个类中,一般把它放析构函数中去调用.

}

//程调用的函数的开始调用EnterCriticalSection结束时调用CriticalSection(&g_criSection);

//在中间有用到的所有资源在被使用时其他线程不能使用(不能读也不能改写).其它两个函数FunOne,GetResult按同样的方法添加这两行代码.这里不再写出来了.

UINT FunOne(LPVOID pParam){

EnterCriticalSection(&g_criSection); //表示进入临界区

for(int i =0; i < 4; i){

g_charArray[i] = 'S';

Sleep(1);

}

LeaveCriticalSection(&g_criSection); //离开临界区

return 0;

}

MFC中的临界区类

MFC把上面的操作封装成一个类CCriticalSection,使用函数Lock与Unlock表示进入和离开临界区.上锁和解锁的说法是更符合我们的习惯思维的.

#include "afxmt.h" //需要添加该头文件引用

CCriticalSection g_criSection;

void MainTestFun{

char g_charArray[4];

CString szResult;

AfxBeginThread(FunOne,NULL);

AfxBeginThread(FunTwo,NULL);

AfxBeginThread(GetResult,); //此时得到的总是BBBB或者SSSS,哪一个线程拥有临界区不确定.只能保证某一个时间只能有一个线程拥有}

//其它两个类也同样加上这两行代码

UINT FunOne(LPVOID pParam){

g_criSection.Lock()//给所有使用的资源上锁

for(int i =0; i < 4; i){

g_charArray[i] = 'S';

Sleep(1);

}

g_criSection.UnLock(); //给使用的资源解锁

return 0;

}

其他线程同步的方法

使线程同步共有4种方法:

1.临界区(critical section)

2.事件(event)

3.信号量(Semaphore)

4.互拆量(Mutex)

其中1临界区是用户对象,所以没太多权限,只能处理同一个进程内的线程同步

而剩下的2,3,4都是内核对象,权限比较大,可以跨进程使用,因此能够处理不同进程间的线程同步问题.

其中的Mutext和临界区适用的场景基本上一样,只不过Mutext是内核对象,而critical section是用户对象

以上就是关于initializecriticalsection的全部内容,相信你一定会非常满意,。


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/ruanjian/article-16414-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      热点图片
      拼命载入中...