C ++ 20中的新线程(jthread)功能

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C ++ 20中的新线程(jthread)功能相关的知识,希望对你有一定的参考价值。

参考技术A

C ++ 20带来了许多很酷的新功能,其中一个我将在这里简单介绍一下: std::jthread 。

这个的实现 std::jthread 基于已经存在的 std::thread 。它基本上是一个包装器,它为线程带来了两个新功能: 默认情况下, 它们可以 协同中断 加入 。在深入研究这两个术语之前,请注意该 std::jthread 对象包含 std::thread 一个成员,提供完全相同的公共函数,这些函数只是向下传递调用。这使我们可以将任何内容更改 std::thread 为 std::jthread ,确保它将像以前一样工作。

该名称表明新的 jthread 是可中断的,即有一种方法可以阻止来自外部的线程。与C ++不同,在其他一些语言中, 线程 类具有 abort() , stop() 或 interrupt() 函数,而且大部分都不是用户可能期望的,即kill开关。有些人可能会认为我们没有这样的东西是如此糟糕, std::thread 而且现在 std::jthread 我们终于拥有了它。但它可以 协作 中断,理解这一点的最好方法是看一下它的功能: request_stop() 。这个名字的选择非常谨慎。考虑这个例子:

这里主线程创建一个新线程,它每秒都会重复执行某些操作(打印一行)。然后主线程继续执行5秒的作业,之后等待另一个线程完成。但它不会完成,它将继续运行,主线程将继续等待。

我们刚刚改变了 thread , jthread 并且,正如所承诺的,没有任何新的事情发生,它表现得像以前一样。现在让我们使用该函数在 main 完成后停止线程。

这编译并且有效,但它不会立即停止执行该线程,也不会停止执行。这没关系:注意,它说 请求 停止,而不是 坚持 或 强制 。所以我们(从线程外部)只能请求停止,并且该线程本身具有最终发言权。这就是它可以 协作 中断的原因。

这终于奏效了。当然,我们可以通过原子布尔来实现这一点,这是一个更广泛和值得信赖的版本。但问题仍然存在: 我们为什么不在jthread上使用killswitch,特别是当其他语言(其他语言)这样做时? 答案是:其他人没有真正拥有它,你也不想拥有它。

假设您已经从 线程创建了一个 工作 线程,并且在某些时候,您想要杀死它( 工作者 )。想象一下,有一个杀戮开关,一个功能: stop()

这几乎总能保证 死锁 内存泄漏 或两者兼而有之。所以这绝对是一个坏主意,无论如何都需要进行一些 清理 。其他语言主要做的是向 工人 抛出一个例外,它负责捕捉和 清理 你的肩膀。让我们不要忘记,这 std::thread 只是一个封面,而且大部分都是一个 pthread 底层。它也有几分相似,我们总是能获得 native_handle() 来自 std::thread 与它合作。但它更复杂。

是的,这很复杂。不要费心阅读。

但这个想法是一样的:在使用“killswitch”之前,你应该自己处理清理工作。

现在,假设您正在发明一种支持多线程并具有 Thread 类的新语言。您是否会给它一个 stop 功能,这个功能并不是名称所暗示的,并且存在滥用的高风险?我不会,因此用户被迫以正确的方式找到方法。

第二个特征 jthread 是帮助我们解决 std::thread 以前导致的困境: join 或 detach *。现在 jthread 来承担一些责任。它的析构函数简单地实现为:

这正是我们在上面的示例中所做的,因此我们可以删除那里的最后两行。

但是,为什么 join 被选为一个jthread默认结束了吗?首先,它与 detach 相比非常安全 而且在大多数情况下,这是你真正需要的。

尽管它附带了C ++ 20,但它 std::jthread 并没有使用任何新的语言功能,所以它现在几乎可用。这是由提出它的人Nicolai Josuttis 实施 的。您可以使用此存储库中的两个头文件来完全访问此新功能:“ sources /”中的 “ jthread.hpp” 和“ *stop_token.hpp * ” 。

翻译自: https://medium.com/@vgasparyan1995/a-new-thread-in-c-20-jthread-ebd121ae8906

C语言数组问题?

#include <stdio.h>
int main(void)
char a[]=0;
char *b;
b=&a[0];
scanf("%c%c%c",b,b+1,b+2);
printf("%c%c%c",*b,*(b+1),*(b+2));
scanf("%c%c%c",b+5,b+6,b+7);
printf("%c%c%c",*b,*(b+1),*(b+2));
printf("%c%c%c",*(b+5),*(b+6),*(b+7));
getchar();
getchar();
return 0;

这个为什么不能运行?
放第二次输入时,就会出现问题!

您好,很高兴回答您的问题。
通过阅读您的程序,我想出现错误的原因应该在char a[]=0这句话,因为没有确定数组的长度,所以只能根据后面赋值的数据个数决定数组长度,但是恰好又只赋值了一个数,那么系统就会认定这个数组的长度为1。那么在后面将a[0]的地址赋值给指针变量b,因为a数组只有一个长度,所以后面的b+1,b+2…等等就是不确定的值,所以程序就会出错。
参考技术A

图中红色框内数组声明只有一个元素,也就是说数组大小是1,后面输入3个元素放哪里,放到不是数组的内存里那肯定会失败。

改成char a[10]=0;

注意这样也是只能放10个元素。想要更多改数字。

追问

如果只能放一个数字,那么我为什可以放123三个字符?

追答

你可以使用sizeof(a)看看它多大。你问的这个问题,是因为在c.语言里就算越界也不一定会崩溃,有可能你占用的还是你这个程序的内存空间或者系统没有强制保护的内存,所以给你的错觉是好像也可以用。如果占用保护的就会程序崩溃。

以上是关于C ++ 20中的新线程(jthread)功能的主要内容,如果未能解决你的问题,请参考以下文章

GB28181 收包方式jrtplib使用方式的差异

JT808协议设备终端模拟软件仿真 工具 网络串口调试

不创建新线程的 C# 异步

技术实操如何使用GoLang将JT808协议中的DWORD类型转为string?

如何禁用 gdb 中的新线程/线程退出消息?

检测何时将对象传递给 C++ 中的新线程?