程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 多線程之互斥鎖(By C++),互斥by

多線程之互斥鎖(By C++),互斥by

編輯:C++入門知識

多線程之互斥鎖(By C++),互斥by


  首先貼一段win32API實現的多線程的代碼,使用CreateThread實現,如果不要傳參數,就把第四個參數設為NULL

  

#include<Windows.h>
#include<iostream>
using namespace std;

//有參數
DWORD WINAPI MyThread_lpParamter(LPVOID lpParamter)
{
    string *lp = (string *)lpParamter;
    while (1)
    {

        cout << "MyThread1 Runing :"<<lp->c_str()<<""<< endl;
        Sleep(5000);
    }
}

int main()
{
    string parameter = "我是參數";
    HANDLE hThread2 = CreateThread(NULL, 0, MyThread_lpParamter, &parameter, 0, NULL);
    CloseHandle(hThread2);
    while(1);
    return 0;
}

下面是執行的結果

 

互斥鎖:

  當一個全局的共有資源被多個線程同時調用會出現意想不到的問題,比如你去銀行取出所有錢,同時又轉所有錢到支付寶,如果這兩塊同時執行,就有可能轉出雙倍的錢,這是不允許的。

這時候要使用的這個線程需要將這個資源(取錢這個過程)先“鎖”起來,然後用好之後再解鎖,這期間別的線程就無法使用了,其他線程的也是類似的過程。

#include<Windows.h>
#include<iostream>
using namespace std;
//互斥鎖
HANDLE hMutex1;
int flag;

DWORD WINAPI MyThread2(LPVOID lpParamter)
{
    while (1)
    {
    //沒上鎖的話就自己鎖上,否則等著 WaitForSingleObject(hMutex1,INFINITE); flag=!flag; cout << "MyThread1 Runing :"<<"線程2"<<" "<<flag<< endl; Sleep(1000);
     //解鎖 ReleaseMutex(hMutex1); } } DWORD WINAPI MyThread1(LPVOID lpParamter) { while (1) { WaitForSingleObject(hMutex1,INFINITE); flag=!flag; cout << "MyThread2 Runing"<<"線程1" <<" "<<flag<< endl; Sleep(10); ReleaseMutex(hMutex1); } } int main() { //創建一個鎖 hMutex1 =CreateMutex(NULL,FALSE,NULL); HANDLE hThread1 = CreateThread(NULL, 0, MyThread1, NULL, 0, NULL); CloseHandle(hThread1); HANDLE hThread2 = CreateThread(NULL, 0, MyThread2, NULL, 0, NULL); CloseHandle(hThread2); while(1); return 0; }

可以看到結果,就算線程1延時的時間非常短,但是由於線程2執行的時候,就被鎖住了,線程1就處於等待。結果就是線程1和線程2會交替執行

多進程互斥:

如果某個文件不允許被多個進程用時使用,這時候也可以采用進程間互斥。當一個進程創建一個進程後創建一個鎖,第二個進程使用OpenMutex獲取第一個進程創建的互斥鎖的句柄。

第一個進程:

#include<Windows.h>
#include<iostream>
using namespace std;
//互斥鎖
HANDLE hMutex1;
int flag;
DWORD WINAPI MyThread(LPVOID lpParamter)
{
    while (1)
    {
        WaitForSingleObject(hMutex1,INFINITE);
        flag=!flag;
        cout << "MyThread2 Runing"<<"進程1" <<" "<<flag<< endl;
        Sleep(500);
        //此時鎖1被鎖,無法在下面解鎖2
        ReleaseMutex(hMutex1);

    }
}
int main()
{
    //創建一個鎖
    hMutex1  =CreateMutex(NULL,false,LPCWSTR("hMutex1"));
    HANDLE hThread1 = CreateThread(NULL, 0, MyThread, NULL, 0, NULL);
    CloseHandle(hThread1);
    while(1);
    return 0;
}

第二個進程:

#include<Windows.h>
#include<iostream>
using namespace std;
//互斥鎖
HANDLE hMutex1;
int flag;
//無參數
DWORD WINAPI MyThread(LPVOID lpParamter)
{
    while (1)
    {
        WaitForSingleObject(hMutex1,INFINITE);
        flag=!flag;
        cout << "MyThread2 Runing"<<"進程2" <<" "<<flag<< endl;
        Sleep(5000);
        ReleaseMutex(hMutex1);
    }
}

int main()
{
    //打開
    hMutex1  = OpenMutex(MUTEX_ALL_ACCESS,false,LPCWSTR("hMutex1"));
    if(hMutex1!=NULL)
        cout<<"鎖打開成功"<<endl;
    HANDLE hThread1 = CreateThread(NULL, 0, MyThread, NULL, 0, NULL);
    CloseHandle(hThread1);
    while(1);
    return 0;
}

結果可以看到,之運行進程1,消息打印的非常快,但是把進程2打開之後,進程1的消息打印速度就跟進程2變得一樣了。

 

死鎖:

何為死鎖,舉個例子,兩個櫃子,兩個鎖,兩把鑰匙,把兩把鑰匙放進另外一個櫃子,然後鎖上,結果呢,兩個都打不開了。在程序內部,這樣就會導致兩個進程死掉。

看例子

#include<Windows.h>
#include<iostream>
using namespace std;
//互斥鎖
HANDLE hMutex1;
HANDLE hMutex2;
int flag;
DWORD WINAPI MyThread2(LPVOID lpParamter)
{
    while (1)
    {
        WaitForSingleObject(hMutex1,INFINITE);
        flag=!flag;
        cout << "MyThread1 Runing :"<<"線程1"<<" "<<flag<< endl;
        Sleep(1000);

        //此時鎖2被鎖,無法在下面解鎖1
        WaitForSingleObject(hMutex2,INFINITE);
        ReleaseMutex(hMutex2);
        ReleaseMutex(hMutex1);
    }
}
DWORD WINAPI MyThread1(LPVOID lpParamter)
{
    while (1)
    {
        WaitForSingleObject(hMutex2,INFINITE);
        flag=!flag;
        cout << "MyThread2 Runing"<<"線程1" <<" "<<flag<< endl;
        Sleep(1000);

        //此時鎖1被鎖,無法在下面解鎖2
        WaitForSingleObject(hMutex1,INFINITE);
        ReleaseMutex(hMutex1);
        ReleaseMutex(hMutex2);

    }
}


int main()
{
    //創建一個鎖
    hMutex1  =CreateMutex(NULL,FALSE,NULL);
    hMutex2  =CreateMutex(NULL,FALSE,NULL);
    HANDLE hThread1 = CreateThread(NULL, 0, MyThread1, NULL, 0, NULL);
    CloseHandle(hThread1);

    HANDLE hThread2 = CreateThread(NULL, 0, MyThread2,NULL, 0, NULL);
    CloseHandle(hThread2);
    while(1);
    return 0;
}

結果呢就是,兩個線程執行打印一次就死掉了

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved