c++11の数据竞争和互斥对象

一、数据竞争的产生

在下面例子中:

void function_1() 
{
    for (int i = 0; i < 100; i++)
    {
        std::cout << "from function 1:" << i << std::endl;
    }
    
}

int main()
{
    std::thread t(function_1);

    for (int i = 0; i < 100; i++)
    {
        std::cout << "from function main:"<<i<<std::endl;
    }

    t.join();

    std::getchar();

    return 0;
}
View Code

我们发现其输出的毫无规律,因为主线程和子线程同时调用cout对象造成的,产生了数据竞争

二、互斥对象

上面的问题可以通过互斥对象来解决

#include "stdafx.h"
#include <iostream>
#include <thread>
#include <mutex>
#include <string>
using namespace std;
std::mutex mu;

void share_print(std::string msg,int id) 
{
    mu.lock();
    cout << msg << id << endl;
    mu.unlock();
}

void function_1() 
{
    for (int i = 0; i < 100; i++)
    {
        share_print("from function 1:",i);
    }
    
}

int main()
{
    std::thread t(function_1);

    for (int i = 0; i < 100; i++)
    {
        share_print("from main:", i);
    }

    t.join();

    std::getchar();

    return 0;
}

但是如果cout中发现异常,那么程序将被永远锁住,除非能够保证要锁住的对象不会出现问题,有此引出一下方法

void share_print(std::string msg,int id) 
{
    std::lock_guard<std::mutex> gard(mu);
    cout << msg << id << endl;

}
View Code

此类并不能阻止其他线程调用cout

三、LogfFile类

 class LogfFile
{
public:
    LogfFile() {
        f.open("log.txt");
    }
    void share_print(std::string msg, int id)
    {
        std::lock_guard<std::mutex> gard(m_mutex);
        f << msg << id << endl;

    }

private:
    std::mutex m_mutex;
    std::ofstream f;
};





void function_1(LogfFile & log)
{
    for (int i = 0; i < 100; i++)
    {
        log.share_print("from function 1:",i);
    }
    
}

int main()
{
    LogfFile log;
    std::thread t(function_1,ref(log));

    for (int i = 0; i < 100; i++)
    {
        log.share_print("from main:", i);
    }

    t.join();

    std::getchar();

    return 0;
}
View Code

注意f不能对外开放

 

 多线程一----多线程的应用

 多线程二----简单线程管理

多线程三----数据竞争和互斥对象

多线程四----死锁和防止死锁

多线程五----unick_lock和once_flag

多线程六----条件变量

多线程七----线程间通信

posted @ 2019-02-28 11:56  卖雨伞的小男孩  阅读(529)  评论(0编辑  收藏  举报