admin管理员组文章数量:1567747
临界区为非内核对象,优点速度快,效率高,缺点时间不好控制,有可能第二个线程永远进不去 所以需要人为的在执行完原子操作后sleep()把进入的线程的时间片让出来
和mutex相似,也是进去一个就关门了 唯一不同的是两个函数的使用时候存在死锁的问题,不是操作系统控制,时间片不好控制
下面为死锁问题复现
下面刚进去a 睡眠20ms 20ms是人为放大的间隙那边b进去了等到释放a才能进去 而这边要等到b释放了 才能进去释放a 所以互相等 一直等
#include "iostream"
#include "windows.h"
using namespace std;
int g_iticket = 100;
unsigned long _stdcall bar(void*pramater);
unsigned long _stdcall bar1(void*pramater);
CRITICAL_SECTION csA; //临界区 非内核让出时间片的时候需要手动给一个sleep 工作在用户区
CRITICAL_SECTION csB;
int main(void)
{
int inum1 = 1;
int inum2 = 2;
HANDLE thread1 = CreateThread(nullptr, 0, bar, &inum1, 0, nullptr);
HANDLE thread2 = CreateThread(nullptr, 0, bar1, &inum2, 0, nullptr);
InitializeCriticalSection(&csA);
InitializeCriticalSection(&csB);
if (thread1)
{
CloseHandle(thread1);
}
if (thread1)
{
CloseHandle(thread2);
}
Sleep(8000);
return 0;
}
//临界区死锁问题示例
unsigned long _stdcall bar(void*pramater)
{
int* inum = reinterpret_cast<int *>(pramater);
while (true)
{
EnterCriticalSection(&csA);
//Sleep(20); //人为放大这个间隙 将时间片让出来, 这个线程拿到了csa 后在这里睡20ms ,下面的线程拿到了csb,上面sleep结束后等csb,下面结束后又在等csa 就这样形成一直等的死锁问题
EnterCriticalSection(&csB);
if (g_iticket > 0)
{
cout << "#" << *inum << ":" << g_iticket-- << endl;
LeaveCriticalSection(&csB);
LeaveCriticalSection(&csA);
Sleep(20); //
}
else
{
LeaveCriticalSection(&csB);
LeaveCriticalSection(&csA);
break;
}
}
return 0;
}
unsigned long _stdcall bar1(void*pramater)
{
int* inum = reinterpret_cast<int *>(pramater);
while (true)
{
EnterCriticalSection(&csB);
//Sleep(20);
EnterCriticalSection(&csA);
if (g_iticket > 0)
{
cout << "#" << *inum << ":" << g_iticket-- << endl;
LeaveCriticalSection(&csA);
LeaveCriticalSection(&csB);
Sleep(20);//
}
else
{
LeaveCriticalSection(&csA);
LeaveCriticalSection(&csB);
break;
}
}
return 0;
}
本文标签: 死锁临界CRITICALSECTION
版权声明:本文标题:临界区 CRITICAL_SECTION 死锁问题解析 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/xitong/1726269938a1063699.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论