天天看點

C++并發與多線程程式設計--啟動、結束、join、detach1、線程的簡單使用2、其他建立線程的方法

1、線程的簡單使用

void myprint()
{
    cout << "線程開始執行" << endl;
    //...
    cout << "線程結束執行"<< endl;
}

#include <thread>
//.....

int main()
{
	thread mytobj1(myprint);//建立了一個線程,線程執行起點(入口)myprint();(2)myprint線程開始執行
	mytobj1.join(); 		//主線程阻塞到這裡等待myprint()執行完成,當子線程執行完畢,這個join就執行完成,主線程就繼續往下執行
	
	thread mytobj2(myprint); 
	mytobj2.detech(); 		//主線程和子線程分開執行,主線程不需要燈态子線程執行完成,可以繼續往下執行。
	
	mytobj2.joinable();		//判斷是否可以成功使用join或者detach,傳回true(可以join或者detach)或者false(不可以join或detach)
}
           

(1)join() 函數

阻塞模式,主線程阻塞到這裡等待子線程函數執行完成,當子線程執行完畢,這個join就執行完成,主線程就繼續往下執行。

(2)detech()函數

非阻塞模式,主線程和子線程分開執行,主線程不需要燈态子線程執行完成,可以繼續往下執行。子線程在背景運作,相當于被C++運作時庫接管,當子線程執行完成,由運作時庫負責清理該子線程的資源。一旦detach,子線程已經被C++運作時庫接管,不能再join。

(3)joinable()函數

判斷是否可以成功使用join或者detach,傳回true(可以join或者detach)或者false(不可以join或detach).

2、其他建立線程的方法

(1)用類對象(可調用對象)

#include <iostream>
#include <thread>

class TA
{
public:
	int &m_i;

	TA(int &i):m_i(i)
	{
		std::cout << "TA ()構造函數被執行" << std::endl;
	}

	TA(const TA& ta):m_i(ta.m_i)
	{
		std::cout << "TA 拷貝構造函數被執行" << std::endl;
	}

	~TA()
	{
		std::cout << "TA 析構函數被執行" << std::endl;
	}

	void operator()()   //不帶參數
	{
		//列印1
		std::cout << "m_i1的值為" << m_i << std::endl;
		std::cout << "m_i2的值為" << m_i << std::endl;
		std::cout << "m_i3的值為" << m_i << std::endl;
		std::cout << "m_i4的值為" << m_i << std::endl;
	}
};

int main()
{
	int myi = 6;

	TA ta(myi);
	std::thread mytobj2(ta);     //ta:可調用對象
	mytobj2.join();				 //(1)等待子線程結束
	//mytobj2.detach();			 //(2)問題:detach主線程和子線程分開執行,當主線程執行完成後,子線程還在背景執行,
								 //而myi為局部變量,此時類中的列印1會出現不可預料的結果
    std::cout << "Hello World!\n";

	getchar();
}

           

源碼中(1)和(2)的執行結果如下:

C++并發與多線程程式設計--啟動、結束、join、detach1、線程的簡單使用2、其他建立線程的方法
C++并發與多線程程式設計--啟動、結束、join、detach1、線程的簡單使用2、其他建立線程的方法

主線程結束後,而ta也為局部變量,ta對象也銷毀了,為什麼子線程還可以繼續執行?

這是因為ta被複制到了子線程中去,隻要TA類對象裡沒有引用,沒有指針,那麼就不會産生問題。

(2)用lambda表達式

auto mylamthread = [] {
	std::cout << "線程3開始執行了" << std::endl;
	//....
	std::cout << "線程3執行結束了" << std::endl;
};

int main()
{
	//int myi = 6;

	//TA ta(myi);
	//std::thread mytobj2(ta);     //ta:可調用對象
	mytobj2.join();			 //(1)等待子線程結束
	//mytobj2.detach();			 //(2)

	std::thread mytobj3(mylamthread);
	mytobj3.join();

    std::cout << "Hello World!\n";

	getchar();
}

           

運作結果:

C++并發與多線程程式設計--啟動、結束、join、detach1、線程的簡單使用2、其他建立線程的方法