-
Notifications
You must be signed in to change notification settings - Fork 128
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
关于 C++CoreGuidelines
对于 detach
的描述
#190
Comments
脱附的线程可能还能会持有直接从操作系统获得的资源;此时合法性取决于 OS 的设计。 另外我工作中参与的项目经常有“线程已经 |
这段话描述的很好,也是我想的。
我能理解的应该是:已经被 detach 的线程,其最后的操作执行,主线程还没结束,也就能保证被 detach 的线程的正确执行,在此之后它即使晚点结束也无所谓,毕竟也都执行完了需要的操作,对吧? |
那么问题来了,能否找到一个平台,能让已经被 detach 的线程,且主线程和进程结束,这个线程依然能成功执行一些任务? |
你看下哪个平台不行,注意不要依赖标准库的对象,后续读写都依赖 OS API。 |
b乎里写了的那个示例是使用的 |
#include<iostream>
#include<thread>
#include<unistd.h>
#include<fcntl.h>
using namespace std::chrono_literals;
void f(){
std::this_thread::sleep_for(2s);
int fd = open("test2.txt",O_RDWR+O_CREAT);
write(fd,"🤣🤣",sizeof("🤣🤣"));
}
int main(){
std::puts("main");
std::thread t{f};
t.detach();
std::puts("main end");
} ubuntu22.04 无效,没有办法创建出新的文件进行读写。 如果把
|
搞那么复杂干啥……你调用pthread_exit的函数把主线程干掉不就行了。主线程里会处理申请的资源(当然也包括申请的线程),结束掉主线程就不会清理资源。 |
教教,写个示例给窝, |
#include<iostream>
#include<cstdint>
#include<vector>
#include<fstream>
#include<thread>
#include<chrono>
#ifdef _MSC_VER
#include<windows.h>
#else
#include<pthread.h>
#endif
void test_thread() {
std::cout << "test thread" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(3));
// 在此处打断点查看进程会发现只有一个线程
std::cout << "after sleep" << std::endl;
}
int main() {
std::cout << "main" << std::endl;
std::thread th(test_thread);
th.detach();
std::cout << "after thread" << std::endl;
#ifdef _MSC_VER
ExitThread(0);
#else
pthread_exit(0);
#endif
} |
struct foo {
foo() { std::cout << "foo()\n"; }
~foo() { std::cout << "~foo()\n"; }
} X;
int main(){ 程序会跳过X的析构,所以这个ExitThread(0)其实是把后面的资源回收工作全都跳过了从而救活了这个detach的thread 具体机制我看要么是libstdc++把回收放在了一个另外的地方调度要么是pthread_exit做了一些转移资源的工作 |
主线程都没了,无法处理资源释放了。可以自己创建一个线程去释放资源: #include<iostream>
#include<cstdint>
#include<vector>
#include<fstream>
#include<thread>
#include<chrono>
#ifdef _MSC_VER
#include<windows.h>
#else
#include<pthread.h>
#endif
void test_thread() {
std::cout << "test thread\n";
std::this_thread::sleep_for(std::chrono::seconds(3));
// 在此处打断点查看进程会发现只有两个线程,还有一个test_exit
std::cout << "after sleep\n";
}
void test_exit() {
std::cout << "test exit\n";
std::this_thread::sleep_for(std::chrono::seconds(5));
exit(0);
}
struct foo {
foo() { std::cout << "foo()\n"; }
~foo() { std::cout << "~foo()\n"; }
} X;
int main() {
{
std::cout << "main\n";
std::thread th(test_thread);
th.detach();
std::thread ex(test_exit);
ex.detach();
std::cout << "after create thread\n";
}
#ifdef _MSC_VER
ExitThread(0);
#else
pthread_exit(0);
#endif
} 主线程借尸还魂?(大雾 |
你看看这3秒后test_thread,5秒后test_exit,是不是怎么看怎么是join。该join就join。 我认为是不能在main里又ExitThread又std::exit的,显然会导致不少资源double free ExitThread:
std::exit:
|
首先,我给出的例子并不是要告诉你推荐你在主线程里使用 至于资源释放问题是并不存在 double free 问题,因为 你说的其他问题:
|
这整个讨论不就是说detach的错误使用方式,指望detach线程在主线程结束之后的行为是错误设计。
|
“指望detach线程在主线程结束之后的行为是错误设计”这个的确,这个目前是共识,很多人使用 但是我们目前在说的就是,有没有平台,在主线程乃至当前进程结束之后,被 |
其实还看了一下 _endthreadex
似乎也做不到保证这个资源管理不出现问题 |
你们不要直接把一整个 comment 都给 quote reply 了,quote 要简明扼要一些的 X _ X |
啥意思? |
https://github.com/Mq-b/Loser-HomeWork/blob/main/C++CoreGuidelines解析/第4章-函数.md#f53-在非局部使用包括要被返回存储在堆上或要传给其他线程的-lambda-表达式中避免通过引用来捕获
英文原书都一个意思
在新版的 C++CoreGuidelines F.53 中,倒是没有了这段描述。
我想讨论目前描述的合理性,用户使用 detach 应该必然要求且保证 detach 的线程在主线程、进程执行完毕之前,就会结束。如果没有,那也不单单是 std::cout 会出现问题了。
比如b乎聊过的。
The text was updated successfully, but these errors were encountered: