美文网首页
2018-11-22 std::thread(c++)傻瓜教程

2018-11-22 std::thread(c++)傻瓜教程

作者: orb学习 | 来源:发表于2018-11-22 11:11 被阅读0次

    新建多线程工程

    1. cmake文件 加入编译选项c11和多线程
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}  -Wall -std=c++11 -pthread -g -march=native")
    

    很重要!!不然会爆出错误

    在函数‘std::thread::thread<void (*)()>(void (*&&)())’中:
    /usr/include/c++/5/thread:137:对‘pthread_create’未定义的引用
    
    1. 包括头文件#include<thread>
    2. 新建线程
      使用thread 线程名来新建线程
    #include <iostream>
    #include<thread>
    #include<unistd.h>
    
    using namespace std;
    
    void sayHello() {
        while (1) {
            sleep(1);
            cout << endl << "hello" << endl;
        }
    }
    
    void sayWorld() {
        while (1) {
            sleep(1);
            cout << endl << "world" << endl;
        }
    }
    
    int main() {
        thread threadHello(&sayHello);
        thread threadWorld(&sayWorld);
        threadHello.join();
        threadWorld.join();
        return 0;
    }
    

    代码解析:

    • c++在新建一个线程thread threadHello(&sayHello);,在新建的过程会自动调用线程内容,所以新建的位置需要注意。
    • threadHello.join();的意思是外在的线程(一般为主线程)等待*this线程(这里就是threadHello线程)的完成,阻塞外在的线程。
    • thread其他方法.detach(),调用之后,目标线程就成为了守护线程,驻留后台运行,与之关联的std::thread对象失去对目标线程的关联,无法再通过std::thread对象取得该线程的控制权。当线程主函数执行完之后,线程就结束了,运行时库负责清理与该线程相关的资源。
      当一个thread对象到达生命期终点而关联线程还没有结束时,则thread对象取消与线程之间的关联,目标线程线程则变为分离线程继续运行。
      注意:在主线程未执行完前并没有销毁,仍会继续执行。
    • 另:若子线程不写join阻塞主线程或detach后台运行,不管子线程是否被执行完毕。都会爆出warning:terminate called without an active exception
      这是指就是子线程还在运行,主进程就退出导致了该错误。即使你认为子线程已经结束,但系统没有通过join之类的阻塞解除之类的方法判断,都会爆出这个warning。

    线程死锁方法(unique_lock的使用)

    1. 定义:
      unique_lock中的unique表示独占所有权。
      unique_lock独占的是mutex对象,就是对mutex锁的独占。
    2. 用法:
      (1)新建一个unique_lock 对象
      (2)给对象传入一个std::mutex 对象作为参数;
      std::mutex mymutex;
      unique_lock lock(mymutex);
    3. 解锁
      因此加锁时新建一个对象lockunique_lock lock(mymutex);,而这个对象生命周期结束后自动解锁。
    4. 参考代码
    #include <iostream>
    #include<thread>
    #include<unistd.h>
    #include<mutex>
    
    using namespace std;
    std::mutex mymutex;
    
    void sayHello() {
        int k = 0;
        unique_lock<mutex> lock(mymutex);
        while (k < 2) {
            k++;
            cout << endl << "hello" << endl;
            sleep(2);
        }
    }
    
    void sayWorld() {
        unique_lock<mutex> lock(mymutex);
        while (1) {
            cout << endl << "world" << endl;
            sleep(1);
        }
    }
    
    int main() {
        thread threadHello(&sayHello);
        thread threadWorld(&sayWorld);
        threadHello.join();
        threadWorld.join();
        return 0;
    }
    

    程序运行步骤是这样的:
    首先同时运行threadHello线程和threadWorld线程
    先进入threadHello线程的sayHello()函数,这个时候加了mymutex锁,另外一个threadWorld线程进入后发现mymutex锁没有释放,只能等待。
    当过去两个循环(每个循环2秒后)threadHello线程结束,unique_lock lock(mymutex)的生命周期结束,mymutex锁释放,执行threadWorld线程,此时开始一直say world。

    参考:

    https://blog.csdn.net/ktigerhero3/article/details/78249266/
    https://zhidao.baidu.com/question/552422613659595372.html

    相关文章

      网友评论

          本文标题:2018-11-22 std::thread(c++)傻瓜教程

          本文链接:https://www.haomeiwen.com/subject/tnwkqqtx.html