b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

C++多线程之使用Mutex和Critical_Section

电脑杂谈  发布时间:2019-09-01 04:07:26  来源:网络整理

ccriticalsection 调用 2次_uploadify 调用2次_ccriticalsection

本文链接:

Mutex和Critical Section都是主要用于限制多线程(Multithread)对全局或共享的数组、对象或存储空间的访问。下面是其主要的优劣点(不同的地方用绿色表示)。

Critical Section

性能和速率

慢。

Mutex是内核对象,相关变量的执行(WaitForSingleObject,

ReleaseMutex)需要用户方式(User Mode)到内核模式

(Kernel Mode)的转换,在x86处理器上这些转化一般要

发费600个左右的CPU指令周期。

快。

Critical Section本身不是内核对象,相关函数

(EnterCriticalSection,LeaveCriticalSection)

的调用通常都在客户体系内执行,在x86处理器上

一般只应该发费9个左右的CPU指令周期。只有

当想要拿到的锁恰好被别的线程拥有时就会退化

成和Mutex一样,即转化到内核机制,发费600个

左右的CPU指令周期。

能否跨越进程(Process)边界

定义写法

HANDLE hmtx;

CRITICAL_SECTION cs;

初始化写法

hmtx= CreateMutex (NULL, FALSE, NULL);

InitializeCriticalSection(&cs);

结束清除写法

CloseHandle(hmtx);

DeleteCriticalSection(&cs);

无限期等待的写法

WaitForSingleObject (hmtx, INFINITE);

EnterCriticalSection(&cs);

0等待(状态检测)的写法

WaitForSingleObject (hmtx, 0);

TryEnterCriticalSection(&cs);

任意时间等待的写法

WaitForSingleObject (hmtx, dwMilliseconds);

锁释放的写法

ReleaseMutex(hmtx);

LeaveCriticalSection(&cs);

能否被一道用于等待其它内核对象

可以(使用WaitForMultipleObjects,

WaitForMultipleObjectsEx,

MsgWaitForMultipleObjects,

MsgWaitForMultipleObjectsEx等等)

当拥有锁的线程死亡时

Mutex变成abandoned状态,其他的期待线程可以获得锁。

Critical Section的状态不可知(undefined),

以后的动作就不能保证了。

自己会不会锁住自己

不会(对已获取的Mutex,重复读取WaitForSingleObject不会

锁住自己。但最终你别忘了要调用同样次数的

ReleaseMutex)

不会(对已获取的Critical Section,重复调用

EnterCriticalSection不会锁住自己。但最终

你别忘了要调用同样次数的

LeaveCriticalSection)

下面是一些补充:

l请先检查你的设计,把不必要的全局或共享对象改为局部对象。全局的东西越少,出问题的或许就越小。

l每次你使用EnterCriticalSection时,请不要忘了在函数的所有可能返回的地方都加上LeaveCriticalSection。对于Mutex也相同。若你把这个问题和Win32 structured exception或C++ exception一起考虑ccriticalsection 调用 2次,你会看到难题并不是那么简洁。自定义一个封装类也许是一种解决方案,以Critical Section为例的代码如下所示:

class csholder

{

CRITICAL_SECTION *cs;

public:

csholder(CRITICAL_SECTION *c): cs(c)

{ EnterCriticalSection(cs); }

~csholder() { LeaveCriticalSection(cs); }

};

CRITICAL_SECTION some_cs;

void foo()

{

// ...

csholder hold_some(&some_cs);

// ... CS protected code here

// at return or if an exception happens

// hold_some's destructor is automatically called

}

l按照你的互斥范围需求的不同ccriticalsection 调用 2次,把Mutex或Critical Section定义为类的成员函数,或者静态类变量。

l若你想限制访问的全局变量只有一个而且类型非常简单(比如是LONG或PVOID型),你也可以使用InterlockedXXX系列数组来保证一个线程写多个线程读。

Demo程序

#include <Windows.h>

#include <iostream>

using namespace std;

int index = 0;

// 临界区结构对象

CRITICAL_SECTION g_cs;

HANDLE hMutex = NULL;

void changeMe()

{

cout << index++ << endl;

}

void changeMe2()

{

cout << index++ << endl;

}

void changeMe3()

{

cout << index++ << endl;

}

DWORD WINAPI th1(LPVOID lpParameter)

{

while(1)

{

Sleep(1600);//sleep 1.6 s

// 进入临界区

EnterCriticalSection(&g_cs);

// 等待互斥对象通知

//WaitForSingleObject(hMutex, INFINITE);

// 对共享资源进行写入操作

//cout << "a" << index++ << endl;

changeMe();

changeMe2();

changeMe3();

// 释放互斥对象

//ReleaseMutex(hMutex);

// 离开临界区

LeaveCriticalSection(&g_cs);

}

return 0;

}

DWORD WINAPI th2(LPVOID lpParameter)

{

while(1)

{

Sleep(2000);//sleep 2 s

// 进入临界区

EnterCriticalSection(&g_cs);

// 等待互斥对象通知

//WaitForSingleObject(hMutex, INFINITE);

//cout << "b" << index++ << endl;

changeMe();

changeMe2();

changeMe3();

// 释放互斥对象

//ReleaseMutex(hMutex);

// 离开临界区

LeaveCriticalSection(&g_cs);

}

return 0;

}

int main(int argc, char* argv[])

{

// 创建互斥对象

//hMutex = CreateMutex(NULL, TRUE, NULL);

// 初始化临界区

InitializeCriticalSection(&g_cs);

HANDLE hThread1;

HANDLE hThread2;

hThread1 = CreateThread(NULL, 0, th1, NULL, 0, NULL);

hThread2 = CreateThread(NULL, 0, th2, NULL, 0, NULL);

int k;

cin >> k;

printf("Hello World!\n");

return 0;

}


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

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

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