c++11 thread多线程创建和传参

c++11 thread多线程创建和传参,第1张

这是 *** 作系统的两个定义,进程好比一个任务,假设你要做一道菜,家里啥原料甚至盐都没有,于是就要买菜->买作料->做菜。这个任务就是可以理解为一个进程。你可以派一个人去买菜买盐回来再做菜,你也可以派两个人一个买盐一个买菜,这里的人好比线程。进程就是线程的容器。

任何程序执行都会有一个主线程,在c++中就是主函数所在的线程,那么其他线程也需要一个函数去执行,不然其他线程鬼知道自己要干什么。

这里我创建了俩函数,分别打印两句话。

接下来就是创建线程,首先我们引入thread这个头文件,然后创建一个thread对象,构造函数参数为咱们的两个线程函数。我们用join()函数表示等待,咱们先试试效果。

最后我们需要定义主线程和这俩线程的关系,因为有时候主线程跑得快,那么主线程就结束了而这俩蜗牛还在搞,那么就会有一系列问题。一般建议让主线程等待这俩货搞完了在结束保证安全,当然也可以自己先跑路。

首先打印线程1开始,接下来本应该打印换行符的,结果让线程2开始抢了先。这是因为这俩线程相互没什么关系,谁快谁慢看电脑心情。最后所有线程退出,主线程就可以结束啦。

这次运行的是join,那么我试试主线程不等待这俩货,为了演示更加清晰,我删除了一个货,留下线程1,再把线程1要干的活加重一点。

打印了什么玩意儿,主线程结束先打,之后换行都没有就线程1开始,然后换了行(也不知道几行),然后啥也没了。为了看得更清楚,我加大了主函数的工作量。

咱不用细讲了,结果就是这样,如果线程先退出,大舅不打印了,但是不代表其他线程就不干活了,活还是在干的。

这里的detach()其实会有很多问题,那就是之后传参的问题,线程函数的参数在创建thread对象时一起传进去。

这里传递了俩参数,一个是int类型,另一个是string引用,还有一个就是指针。之前说过,如果我们用detach,主线程会被回收,那么这里的两个参数会不会被回收,如果回收了,次线程不就没有参数了吗,尤其是这里的string引用和指针。我们探究一下。我们先来一把join看看这两种变量的地址关系。分别打印三个对象的地址

三个变量,只有指所指的对象的地址是相同的。引用的地址居然不同,可见拷贝了,那么在进一步探究,我们自定义类,在拷贝构造函数里打印东西。

我们在三中构造函数里都打印东西,并且输出自定义类对象地址。

发现咱们使用引用是发生了拷贝,那么不用引用呢,其实会发生两次拷贝。如下图

会发现隐式转换是在子线程里干的活,那就危险了。

现在如果执意要使用引用,但是都不能复制,比如多个线程需要 *** 作主线程里同一个对象,指针是一种形式,引用当然也可以,在std空间里,有个函数叫ref(),用它包起来的对象就是真引用,不会发生复制,形参里的const修饰符也可以不用了。

在阅读前,您需要对ThreadLocal用法有一定了解。如果不了解,请参考ThreadLocal用法相关文章。

这个需求或许也很常见,最开始,我们可能会想到InheritableThreadLocal,这是由Jdk为我们提供,他是ThreadLocal的子类,使用方法和ThreadLocal完全相同。

但是这里有几个坑:

1、手动通过线程池创建线程可能会造成get值为null。

2、项目中我们往往会使用线程池,如果主线程使用的是缓存线程池(比如SpringMvc),线程会复用,当线程执行完毕后本次 *** 作后,再次执行新的任务时候,ThreadLocal内部数据并没有被清除。

3、ThreadLocal父子线程之间数据拷贝默认是浅拷贝,这也就意味如果我们多个线程可能会引用同一个内存地址,造成多个线程访问一个对象,轻者会造成线程不安全,重者甚至会ThreadLocal数据被修改成非预期结果。

这些坑本人亲身体验过,血的教训总结出来,那么如何很好的解决这些问题呢?这边给出一个终级解决方案,使用阿里Transmittable ThreadLocal,可以很好的解决上面这些问题。

具体使用方法可以参见文档: >

以上就是关于c++11 thread多线程创建和传参全部的内容,包括:c++11 thread多线程创建和传参、ThreadLocal父子线程数据传递解决方案、等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/9585412.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-29
下一篇2023-04-29

发表评论

登录后才能评论

评论列表(0条)

    保存