三、join、detach

BitAurora
• 阅读 3130

加入式(join):

#include<thread>
#include<iostream>
#include <windows.h>

void myPrintf() {
    Sleep(1000);
    std::cout << "threadRun" << std::endl;
    return;
}

int main()
{
    std::thread t(myPrintf);
    t.join();   //15
    std::cout << "main" << std::endl;
    system("pause");
    return 0;
}
/*输出:
threadRun
main
请按任意键继续. . .
*/

虽然子线程sleep了一秒,但主线程在15行等到子线程结束了才继续往下执行。
t.join()的意思就是是主线程阻塞在这里,等待子线程t结束了才会继续往下执行,

分离式(detach):

#include<thread>
#include<iostream>
#include <windows.h>

void myPrintf() {
    Sleep(1000);
    std::cout << "threadRun" << std::endl;
    return;
}

int main()
{
    std::thread t(myPrintf);
    t.detach();   //16
    std::cout << "main" << std::endl;
    system("pause");
    return 0;
}
/*输出:
main
请按任意键继续. . . threadRun
*/

主线程结束了,子线程才输出threadRun,还在执行,
16行t.detach()意思就是主线程和子线程t分离执行,互不影响。

注意:

启动线程后,你需要明确是要等待线程结束(加入式join),还是让其自主运行(分离式detach)。如果在 std::thread 对象销毁之后才决定(注意这里说的是std::thread 对象销毁之后,而不是子线程结束之后),会触发异常(std::thread 对象销毁时std::thread 的析构函数会调用 std::terminate(),这时再去决定会触发相应异常)

分离

如果想要分离一个线程,可以在线程启动后,直接使用detach()进行分离,但要保证线程结束之前,可访问的数据的有效性。

#include<thread>
#include<iostream>
#include<windows.h>
void fun(int & i) {
    Sleep(1000);
    std::cout << i << std::endl;
    return;
}

void test() {
    int temp = 2;
    std::thread t(fun,std::ref(temp)); //13
    t.detach();                       //14
}

int main()
{
    test();
    system("pause");
    return 0;
}
/*
请按任意键继续. . . 3134432 乱码
*/

13行向线程函数传入了temp的引用,但在线程函数内却输出乱码。由于14行使用了detach,两线程分离,test函数执行完时,会销毁局部变量temp,但线程函数还在运行,并通过temp的引用i访问了已经销毁的变量,所以尽量避免用一个能访问局部变量的函数去创建线程,除非十分确定线程会在函数完成前结束。

加入

如果打算等待对应线程,则需要细心挑选调用join()的位置,包括考虑如果出现异常了能否正确join(在异常处理过程中调用join())。

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
待兔 待兔
1年前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
浩浩 浩浩
5年前
android 面试题总结
Java部分一、多线程 Join() 线程加入,执行此方法的线程优先使用cpu Yeild() 线程释放资源使所有线程能有相等的机会使用cpu Sleep()相当于让线程睡眠,交出CPU,让CPU去执行其他的任务(不会释放锁)。Wait()方法会让线程进入阻塞状态,并且会释放线程占有的锁,并交出CPU执行权限。
Wesley13 Wesley13
4年前
HTTP面试题(二):HTTP请求报文和响应报文格式
!(https://oscimg.oschina.net/oscnet/0406894fb1274bee91fc53c84c516576.jpg)看都看了还不点个赞!(https://oscimg.oschina.net/oscnet/095d444dc9a449ee85afd19b00fdf52b.png)!(h
Stella981 Stella981
4年前
Flink Join
文章目录一.简介二.窗口Join2.1翻滚窗口(TumblingWindowJoin)2.2滑动窗口Join(SlidingWindowJoin)2.3会话窗口Join(SessionWindowJo
Wesley13 Wesley13
4年前
linux线程基本编程
索引:1.创建线程pthread\_create2.等待线程结束pthread\_join3.分离线程pthread\_detach4.创建线程键pthread\_key\_create5.删除线程键pthread\_key\_delete6.设置线程数据pthread\_setspecific7.获取线程数据pth
Wesley13 Wesley13
4年前
Oracle 中的join
1、概述1.1、所有的join连接,都可以加上类似wherea.id'1000'的条件,达到同样的效果。1.2、除了crossjoin不可以加on外,其它join连接都必须加上on关键字,后都可加where条件。1.3、虽然都可以加where条件,但是他们只在标准连接的结果集上查找where条件。比如左外连接的结果没有class的三
Wesley13 Wesley13
4年前
mysql减少join的几种通用方法
1关于join只要参与过后台开发,必然都对join有一定的了解.我们使用join查询,主要为满足两方面的需求:No.需求说明典型相似操作效果对比1查询关联表内容,如主从表之间内容子查询不考虑索引的情况下,join查询效率一般优于前者;即使考虑索引,多数情况子查询的索引并不好设计2多表关系限制in
分布式数据库 Join 查询设计与实现浅析 | 京东云技术团队
文章从常用的关系型数据库MySQL的分库分表Join分析,再到非关系型ElasticSearch来分析Join实现策略。逐步深入Join的实现机制。
Python进阶者 Python进阶者
2年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这