c++多线程(3)

https://paul.pub/cpp-concurrency/

https://zhuanlan.zhihu.com/p/71900518

  1. 一次调用

API

标准

说明

call_once

c++11

在多线程环境下,也能保证某个函数只调用一次

once_flag

c++11

与call_once配合使用

1.1 调用示例

#include <iostream>
#include <thread>
#include <Windows.h>
#include <mutex>
void Init()
{
    std::cout << "进行线程工作" << std::endl;
}
void Worker(std::once_flag* flag)
{
    std::call_once(*flag, Init);
}
int main()
{
    std::once_flag flag;
    std::thread th1(Worker,&flag);
    std::thread th2(Worker, &flag);
    th1.join();
    th2.join();
    return 0;
}

结果显示两个线程里面只有一个成功执行了init函数

1.2 实现线程安全的单例模式

1.2.1 h文件
#pragma once
#include <iostream>
#include <thread>
#include <Windows.h>
#include <mutex>
class COnceThread
{
public:
    static COnceThread* GetInstance();
    static void CInit();
private:
    static COnceThread* cThread;
    COnceThread();
    
};
1.2.2 cpp文件
#include "COnceThread.h"
COnceThread* COnceThread::cThread = nullptr;
COnceThread::COnceThread()
{
    std::cout << "执行了构造函数" << std::endl;
}
void COnceThread::CInit()
{
    cThread = new COnceThread();
}
COnceThread* COnceThread::GetInstance()
{
    static std::once_flag flag;      //static 不能缺少
    //std::call_once(flag, &COnceThread::CInit); //第一种方式
    std::call_once(flag, [&]() {    //第二种方式
        cThread = new COnceThread();
        });
    return cThread;
}
1.2.3 main文件
#include <iostream>
#include "COnceThread.h"
void DoThing()
{
    std::cout << "执行线程" << std::endl;
    COnceThread* woker = COnceThread::GetInstance();
}
int main()
{
    std::thread th1(DoThing);
    std::thread th2(DoThing);
    th1.join();
    th2.join();
    return 0;
}

2.线程同步:

当多个线程要访问同一个资源时,可能产生读写冲突,导致数据混乱,进而引起程序崩溃

使用std::mutex进行上锁、解锁操作,预防读写冲突,需要包含mutex头文件

#include <iostream>
#include <vector>
#include <string>
#include <Windows.h>
#include <thread>
#include <mutex>
class Box
{

};
std::mutex mutex1;
std::vector<Box*> p;
void InitBox()        //初始化箱子
{
    for (int i = 0; i < 9; i++)
    {
        p.push_back(new Box());
    }
    std::cout << "初始有" << p.size() << "个箱子" << std::endl;
}
void MoveBox(std::string name)        //搬走箱子
{
    mutex1.lock();
    if (!p.empty())
    {
        std::cout << name << "搬走了第" << p.size() << "个箱子" << std::endl;
        p.pop_back();
        Sleep(3000);
    }
    else
        return;
    mutex1.unlock();
}
//线程函数
void Fun1()
{
    while (1)
    {
        MoveBox("线程1");
        Sleep(5000);
    }
}
void Fun2()
{
    while (1)
    {
        MoveBox("线程2");
        Sleep(5000);
    }
}
int main()
{
    std::cout << "主线程启动" << std::endl;
    InitBox();
    std::thread th1(Fun1);
    std::thread th2(Fun2);
    th1.join();
    th2.join();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

为阿根廷助威

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值