多线程之互斥锁(By C++)与多进程

多进程相关: https://www.cnblogs.com/LUO77/p/5816326.html


首先贴一段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;
}
复制代码

结果呢就是,两个线程执行打印一次就死掉了

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
《Linux多线程服务端编程:使用muduo C++网络库》主要讲述采用现代C++在x86-64 Linux上编写多线程TCP网络服务程序的主流常规技术,重点讲解一种适应性较强的多线程服务器的编程模型,即one loop per thread。 目 录 第1部分C++ 多线程系统编程 第1章线程安全的对象生命期管理3 1.1当析构函数遇到多线程. . . . . . . . . . . . . . . . .. . . . . . . . . . . 3 1.1.1线程安全的定义. . . . . . . . . . . . . . . . .. . . . . . . . . . . 4 1.1.2MutexLock 与MutexLockGuard. . . . . . . . . . . . . . . . . . . . 4 1.1.3一个线程安全的Counter 示例.. . . . . . . . . . . . . . . . . . . 4 1.2对象的创建很简单. . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . 5 1.3销毁太难. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . 7 1.3.1mutex 不是办法. . . . . . . . . . . . . . . . . . . .. . . . . . . . 7 1.3.2作为数据成员的mutex 不能保护析构.. . . . . . . . . . . . . . 8 1.4线程安全的Observer 有多难.. . . . . . . . . . . . . . . . . . . . . . . . 8 1.5原始指针有何不妥. . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . 11 1.6神器shared_ptr/weak_ptr . . . . . . . . . .. . . . . . . . . . . . . . . . 13 1.7插曲:系统地避免各种指针错误. . . . . . . . . . . . . . . . .. . . . . . 14 1.8应用到Observer 上.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 1.9再论shared_ptr 的线程安全.. . . . . . . . . . . . . . . . . . . . . . . . 17 1.10shared_ptr 技术与陷阱. . . .. . . . . . . . . . . . . . . . . . . . . . . . 19 1.11对象池. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . 21 1.11.1enable_shared_from_this . . . . . . . . . . . . . . . . . . . . . . 23 1.11.2弱回调. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . 24 1.12替代方案. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . 26 1.13心得与小结. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . 26 1.14Observer 之谬. . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 第2章线程同步精要 2.1互斥器(mutex). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 2.1.1只使用非递归的mutex . . . . . . . . . . . . . .. . . . . . . . . . 33 2.1.2死. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . 35 2.2条件变量(condition variable). . . . . . . . . .

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值