​​

死锁

// ssss.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include<stdio.h>
CRITICAL_SECTION cs1;
CRITICAL_SECTION cs2;

int y;

DWORD WINAPI Proc1(LPVOID lpParameter)
{
    for(int i = 0; i < 1000; i++)
    {
        Sleep(1000);
        EnterCriticalSection(&cs1);
        EnterCriticalSection(&cs2);
        printf("1++++++++++:%d\n", ++y);
        LeaveCriticalSection(&cs2);
        LeaveCriticalSection(&cs1);
    }

    return 0;
}

DWORD WINAPI Proc2(LPVOID lpParameter)
{
    for(int i = 0; i < 1000; i++)
    {
        Sleep(1000);
        EnterCriticalSection(&cs2);
        EnterCriticalSection(&cs1);
        printf("2----------:%d\n", ++y);
        LeaveCriticalSection(&cs1);
        LeaveCriticalSection(&cs2);

    }
    return 0;
}


int main(int argc, char* argv[])
{
    HANDLE h1 = ::CreateThread(NULL, 0, Proc1, NULL, 0, NULL);
    ::CloseHandle(h1);
    HANDLE h2 = ::CreateThread(NULL, 0, Proc2, NULL, 0, NULL);
    ::CloseHandle(h2);
    InitializeCriticalSection(&cs1);
    InitializeCriticalSection(&cs2);
    while(1)
    {
    }
    DeleteCriticalSection(&cs1);
    return 0;
}

 

 

 

全局变量X
全局变量Y
全局变量Z

线程1
DWORD WINAPI ThreadFunc(PVOID pvParam)
{
EnterCriticalSection(&g_cs);
使用X
使用Y
LeaveCriticalSection(&g_cs);
return(0);
}

线程2
DWORD WINAPI ThreadFunc(PVOID pvParam)
{
EnterCriticalSection(&g_cs);
使用X
使用Z
LeaveCriticalSection(&g_cs);
return(0);
}

线程3
DWORD WINAPI ThreadFunc(PVOID pvParam)
{
EnterCriticalSection(&g_cs);
使用Y
使用X
LeaveCriticalSection(&g_cs);
return(0);
}

 这样做会导致线程2在使用z的时候,线程1无法使用x;

 

解决方案:
CRITICAL_SECTION g_csX;
CRITICAL_SECTION g_csY;
CRITICAL_SECTION g_csZ;

线程1
DWORD WINAPI ThreadFunc(PVOID pvParam)
{
EnterCriticalSection(&g_csX);
使用X
LeaveCriticalSection(&g_csX);
EnterCriticalSection(&g_csY);
使用Y
LeaveCriticalSection(&g_csY);

return(0);
}

线程2
DWORD WINAPI ThreadFunc(PVOID pvParam)
{
EnterCriticalSection(&g_csX);
使用X
LeaveCriticalSection(&g_csX);
EnterCriticalSection(&g_csZ);
使用Z
LeaveCriticalSection(&g_csZ);

return(0);
}

线程3
DWORD WINAPI ThreadFunc(PVOID pvParam)
{
EnterCriticalSection(&g_csX);
使用X
LeaveCriticalSection(&g_csX);
return(0);
}

 

#include <windows.h>
#include<stdio.h>
CRITICAL_SECTION cs1;

int y;

DWORD WINAPI Proc1(LPVOID lpParameter)
{
    for(int i = 0; i < 1000; i++)
    {
        Sleep(1000);
        EnterCriticalSection(&cs1);

        printf("1++++++++++:%d\n", ++y);
        ExitThread(2);
        LeaveCriticalSection(&cs1);
    }

    return 0;
}

DWORD WINAPI Proc2(LPVOID lpParameter)
{
    for(int i = 0; i < 1000; i++)
    {
        Sleep(1000);
      
        EnterCriticalSection(&cs1);
        printf("2----------:%d\n", ++y);
        LeaveCriticalSection(&cs1);
   

    }
    return 0;
}


int main(int argc, char* argv[])
{
    HANDLE h1 = ::CreateThread(NULL, 0, Proc1, NULL, 0, NULL);
    ::CloseHandle(h1);
    HANDLE h2 = ::CreateThread(NULL, 0, Proc2, NULL, 0, NULL);
    ::CloseHandle(h2);
    InitializeCriticalSection(&cs1);
    while(1)
    {
    }
    DeleteCriticalSection(&cs1);
    return 0;
}
使用临界区当一个线程领走令牌后没有归还令牌前,如果线程意外终止,那么另一个使用相同令牌的临界区线程就会一直卡死不运行,因为被终止的线程没有归还令牌。
posted @ 2020-09-22 18:02  w_athena  阅读(99)  评论(0编辑  收藏  举报