关于std::thread的一些实验

#include <thread>
#include <chrono>
#include <iostream>
#include <unistd.h>
void test()
{
	for(int i=0;i<5;i++){
		std::cout << "111111111" << std::endl;	
		std::this_thread::sleep_for(std::chrono::seconds(1));
	}
	std::cout << "ending" << std::endl;
}

int main()
{
	std::thread *th1 = new std::thread(test);
    sleep(10);
	if(th1->joinable())
	{
		std::cout << "can join" << std::endl;
		th1->join();
	}
	
	return 0;
}

result:
root@ubuntu:~/test/thread # ./a.out
111111111
111111111
111111111
111111111
111111111
ending
can join

线程结束后依旧可联结

#include <thread>
#include <chrono>
#include <iostream>
#include <unistd.h>
void test()
{
	for(int i=0;i<5;i++){
		std::cout << "111111111" << std::endl;	
		std::this_thread::sleep_for(std::chrono::seconds(1));
	}
	std::cout << "ending" << std::endl;

}

int main()
{
	std::thread *th1 = new std::thread(test);
	sleep(10);
	if(th1->joinable())
	{
		if(th1->joinable())
		{
			th1->join();
			std::cout << "can join" << std::endl;
		}
		//add 
		if(!th1->joinable())
		{
			std::cout << "cannot join" << std::endl;	
		}
	}

	return 0;
}

resuit:
root@ubuntu:~/test/thread # ./a.out
111111111
111111111
111111111
111111111
111111111
ending
can join
cannot join

join过的thread不再可联结

#include <thread>
#include <chrono>
#include <iostream>
#include <unistd.h>
void test()
{
	for(int i=0;i<5;i++){
		std::cout << "111111111" << std::endl;	
		std::this_thread::sleep_for(std::chrono::seconds(1));
	}
	std::cout << "ending" << std::endl;

}

int main()
{
	std::thread *th1 = new std::thread(test);
	sleep(10);
	//add
	delete th1;
	if(th1->joinable())
	{
		if(th1->joinable())
		{
			th1->join();
			std::cout << "can join" << std::endl;
		}
		if(!th1->joinable())
		{
			std::cout << "cannot join" << std::endl;	
		}
	}

	return 0;
}

root@ubuntu:~/test/thread # ./a.out
111111111
111111111
111111111
111111111
111111111
ending
terminate called without an active exception
Aborted (core dumped)

std::thread对象析构时,会先判断joinable,如果可联结,则程序会直接终止)(terminate)

#include <thread>
#include <chrono>
#include <iostream>
#include <unistd.h>
void test()
{
	for(int i=0;i<5;i++){
		std::cout << "111111111" << std::endl;	
		std::this_thread::sleep_for(std::chrono::seconds(1));
	}
	std::cout << "ending" << std::endl;

}

int main()
{
	//std::shared_ptr<std::thread> th1(new std::thread(test),[](std::thread*p){delete p;}); //coredump
	std::shared_ptr<std::thread> th1;
	th1.reset(new std::thread(test),[](std::thread*p){std::cout << "not delete" << std::endl;});//normal
	//add
	sleep(2);

	return 0;
}

root@ubuntu:~/test/thread # ./a.out
111111111
111111111
not delete

#include <thread>
  2 #include <chrono>
  3 #include <iostream>
  4 #include <unistd.h>
  5 void test()
  6 {
  7   for(int i=0;i<5;i++){
  8     std::cout << "111111111" << std::endl;
  9     std::this_thread::sleep_for(std::chrono::seconds(1));
 10   }
 11   std::cout << "ending" << std::endl;
 12 
 13 }
 14 
 15 int main()
 16 {
 17   std::thread *th1 = new std::thread(test);
 18   th1->detach();
 19   delete th1;
 20   sleep(10);
 21   return 0;
 22 }

root@ubuntu:~/test/thread # $ ./a.out
111111111
111111111
111111111
111111111
111111111
ending

如果一个 std::thread 对象被析构,而且该线程是 detached 的,那么该线程会继续在后台运行,直到它完成或终止。在这种情况下,析构函数会释放 std::thread 对象所占用的资源,但是并不会等待该线程完成。

这就意味着,尽管 std::thread 对象已经被销毁,但是线程本身仍然在运行。因此,确保在销毁 std::thread 对象之前,该线程能够安全地运行完毕是很重要的。否则,如果线程正在访问已被销毁的对象或资源,可能会导致未定义行为或程序崩溃。

总结:
可联结性
一个 std::thread 对象只可能处于可联结或不可联结两种状态之一。即 std::thread 对象是否与某个有效的底层线程关联。
①.可联结:当线程可运行、已经运行或处于阻塞时是可联结的。但如果某个底层线程已经执行完任务,但是没有被 join 的话,该线程依然会被认为是一个活动的执行线程,仍然处于 joinable 状态。
②.不可联结:不带参构造的std::thread对象为不可联结,因为底层线程还没创建;已经移动的std::thread对象为不可联结;已经调用join或detach的对象为不可联结状态。
③.joinable():判断是否可以成功使用 join() 或者 detach() ,返回true 表示可以,否则返回 false。

std::thread 对象析构
std::thread 对象析构时,会先判断 joinable() ,如果可联结,则程序会直接被终止(terminate)。
因此,在创建 thread 对象以后,要在随后的某个地方显式地调用 join 或 detach 以便让 std::thread 处于不可联结状态。

若将线程detach,随时都可以delete it销毁线程,但貌似无法终止线程运行,否则必须join
后,即跑完线程才可以去delete it;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值