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

新建多线程工程

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

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

在函数‘std::thread::thread(void (*&&)())’中:
/usr/include/c++/5/thread:137:对‘pthread_create’未定义的引用
  1. 包括头文件#include
  2. 新建线程
    使用thread 线程名来新建线程
#include 
#include
#include

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 
#include
#include
#include

using namespace std;
std::mutex mymutex;

void sayHello() {
    int k = 0;
    unique_lock lock(mymutex);
    while (k < 2) {
        k++;
        cout << endl << "hello" << endl;
        sleep(2);
    }
}

void sayWorld() {
    unique_lock 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++)傻瓜教程)