关于C++多线程的一些疑惑

jeff_
  • 39

背景:

最近学习下多线程,无意看到一篇博文,其中有一段自己尝试运行,发现一些问题,请教下各位。当然,作为新手,有些可能是自己理解错误的地方,也希望大家指出,先谢谢各位。

clipboard.png

提出问题:

①.线程是根据所在函数块退出而退出吗?
例如:文中主线程在main()结束return 0退出而退出,子线程在fn函数执行完毕后体退出。(这里可能是最大的误区,因为之前似乎看过这种理论,但是想找找不到了- -.)

自己的推论依据:

下面代码也是和文章有出入的地方。首先,如果没有加上cin.get()进行暂停,代码会直接退出,没有输出结果。(我的看法是主线程和子线程分离后,主线程执行return 0直接退出了,所以没有输出。)

这里也引申了另一个问题,控制台不会给子线程输出结果吗,如果主线程退出了的话?(或者有什么方法可以在主线程即使退出了也能查看子线程的输出)
当我加上cin.get()后(好像就变成了和t.join一样主线程等待分线程退出了欸),但输出就是正确输出(10个100),并不像图中说的*a将成为野指针,图片控制台的输出也没有。

图片文章中理论我大概明白了,但是结果却不近人意,似乎局部变量a地址没有销毁,*a一直输出正确的答案啊?

代码
测试环境:VS2017、Ubuntu -std=c++11。
(代码也不知道是不是这样写 0.0,也尝试了将fn放在main内部,lambda的captures调用fn,结果似乎一致)

#include <iostream>
#include <thread>

using namespace std;

auto fn = [](int *a) {
    for (int i = 0; i < 10; i++)
        cout << *a << endl;
};
int main() {
    
    [] {
        int a = 100;
        thread t(fn, &a);
        t.detach();
    }();

    cin.get();

    return 0;
}
评论
阅读 685
2 个回答
✓ 已被采纳
控制台不会给子线程输出结果吗,如果主线程退出了的话?

从 main 返回会导致 std::exit() 被调用(从其他线程函数返回没有这个效果)。std::exit 会终止整个程序,即使还有其它线程在运行。

但输出就是正确输出(10个100),并不像图中说的*a将成为野指针,图片控制台的输出也没有。
  1. 这段代码并不能保证线程运行结束在 lambda 运行结束之后。所以有可能线程退出的时候 lambda 函数都没有返回。
  2. 如果在 lambda 返回了线程还没有结束,那么线程函数引用了一个生命周期已经结束的对象,这个一个未定义行为。未定义行为,什么都可能发生。

这个问题跟线程关系不大,先解决你为啥*a一直输出正确结果的问题

因为内存释放,不像你想的一样,释放了这一块内存就全是0或者全是0xff了,也不会不让你访问了

内存释放是标记这一段内存为可用内存,除非你指定,否则其值暂时是不会改变的,当有新的内存申请时,这部分内存可能会随时被利用

所以,a确实释放了,但是内存还没来得及变,你依然可以访问这一块内存,按照int*来获取之前付给这一部分内存的值

但是一定要注意,这在c/c++是非常危险的操作,请一定不要这样访问已经释放的变量

撰写回答

登录后参与交流、获取后续更新提醒

宣传栏