C++11多线程编程

1. 基本的多线程实现

#include<iostream>
#include<thread>
#include<string>

using namespace std;
class  Factor {
public:
    void operator()(string &msg) {
            cout << "from t1:" << msg << endl;
            msg = "Read http://blog.csdn.net/hutianyou123";
    }
};
int main()
{
    string s = "http://blog.csdn.net/hutianyou123";
    cout << this_thread::get_id() << endl;
    std::thread t1((Factor()),move(s));
    thread t2 = move(t1);
    cout << t2.get_id() << endl;
    t2.join();

    //thread::hardware_concurrency();
    system("pause");
    return 0;
}

上述代码实现基本的线程调度,在主线程中调用线程t1,并将t1移动到t2中,这是t1为空。且主函数字符串s是通过传地址的方式给线程t1。

2. 主线程与子线程同步问题

#include<iostream>
#include<string>
#include<thread>
#include<mutex>
#include<fstream>

using namespace std;

class Logfile
{
public:
    Logfile() {
        f.open("log.txt");
    }
    void share_print(string msg, int id) {
        lock_guard<mutex>locker(m_mutex);//加同步锁
        f << msg << ":" << id << endl;
        cout << msg << ":" << id << endl;
    }
protected:
private:
    mutex m_mutex;
    ofstream f; 
};


void function_1(Logfile &log) {
    for (int i = 0; i < 100; i++)
        log.share_print("From t1:", i);
}

int main() {
    Logfile log;
    thread t1(function_1,ref(log));
    for (int i = 0; i >-100; i--)
        log.share_print("From main:", i);
    if(t1.joinable())
    t1.join();

    system("pause");
    return 0;
}

输出结果:
这里写图片描述

3. 利用unique_lock实现主从线程同步

#include<iostream>
#include<string>
#include<thread>
#include<mutex>
#include<fstream>
#include<windows.h>
using namespace std;

class Logfile
{
    once_flag m_flag;
public:
    Logfile() {
    }
    void share_print(string msg, int id) {
        call_once(m_flag, [&]() {f.open(("log.txt")); });
        unique_lock<mutex>locker(m_mutex,defer_lock);//加同步锁

        locker.lock();
        cout<< msg << ":" << id << endl;
        locker.unlock();
        f << msg << ":" << id << endl;
    }

private:
    mutex m_mutex;
    ofstream f;

};

void function_1(Logfile &log) {
    for (int i = 0; i < 100; i++)
        log.share_print("From t1:", i);
}

int main() {
    Logfile log;
    thread t1(function_1, ref(log));
    for (int i = 0; i > -100; i--) {
        log.share_print("From main:", i);

    }
    if (t1.joinable())
        t1.join();

    system("pause");
    return 0;
}

lock_guard 加锁保护,可以防止上锁的线程崩溃,而不能及时释放锁。而unique_lock可以提供更多的弹性,可以指定代码同步。用lock/unlock可以灵活的控制加锁同步的范围,但会消耗更多的计算机资源。

4. 如何避免死锁

#include<iostream>
#include<string>
#include<thread>
#include<mutex>
#include<fstream>
#include<windows.h>
using namespace std;

class Logfile
{
public:
    Logfile() {
        f.open("log.txt");
    }
    void share_print(string msg, int id) {
        lock(m_mutex, m_mutex2);//对mutex按照顺序加锁
        lock_guard<mutex>locker(m_mutex,adopt_lock);//加同步锁
        lock_guard<mutex>locker2(m_mutex2,adopt_lock);//加同步锁
        cout<< msg << ":" << id << endl;
    }

    void share_print2(string msg, int id) {
        lock(m_mutex, m_mutex2);
        lock_guard<mutex>locker2(m_mutex2,adopt_lock);//加同步锁
        lock_guard<mutex>locker(m_mutex,adopt_lock);//加同步锁
        cout << msg << ":" << id << endl;
    }
private:
    mutex m_mutex;
    mutex m_mutex2;
    ofstream f;

};

void function_1(Logfile &log) {
    for (int i = 0; i < 100; i++)
        log.share_print("From t1:", i);
}

int main() {
    Logfile log;
    thread t1(function_1, ref(log));
    for (int i = 0; i > -100; i--) {
        log.share_print2("From main:", i);

    }
    if (t1.joinable())
        t1.join();

    system("pause");
    return 0;
}

lock(m_mutex, m_mutex2)有效的避免了死锁的发生,即使t1线程中的调用log.share_print2函数优先对m_mutex2加锁,也是按照lock设定的顺序执行的。

5. 条件变量提高线程效率

#include<iostream>
#include<deque>
#include<string>
#include<thread>
#include<mutex>
#include<fstream>
#include<condition_variable>
using namespace std;
condition_variable cond;
deque<int>q;
mutex mu;

void function_1() {
    int count = 10;
    while (count > 0) {
        unique_lock<mutex>locker(mu);
        q.push_front(count);//给队列加锁
        locker.unlock();
        cond.notify_one();//标注条件变量
        this_thread::sleep_for(chrono::seconds(1));//休眠1秒钟
            count--;
    }

}

void function_2() {
    int data = 0;
    while (data != 1) {
        unique_lock<mutex>locker(mu);//加锁
        cond.wait(locker, []() {return !q.empty(); });//当队列为空,线程处于休眠状态
            data = q.back();//从队列获取数据
            q.pop_back();
            locker.unlock();
            cout << "to got a value from t1: " << data << endl;
    }

}


int main() {
    thread t1(function_1);
    thread t2(function_2);
    t1.detach();//无需等待t1线程运行结束
    t2.join();//等待t2线程运行结束
    system("pause");
    return 0;
}

运行结果:
这里写图片描述

引入c++条件变量,#include,来控制子线程等待时间,使用condition_variable::wait(),表示等待上一个线程完成。
如有问题,请指教,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值