1. 程式人生 > >執行緒傳參,detach的大坑,成員函式做執行緒函式

執行緒傳參,detach的大坑,成員函式做執行緒函式

傳遞臨時物件作為引數

VS shitf+F9
檢視變數

void myprint(const int &t, char *j)
{
	cout << t << endl;
	cout << j << endl;

}

int main()
{
	int m=1;
	int &n = m;
	char mybuf[] = "hello world";

	std::thread mythred(myprint, n, mybuf);
	//mythred.join();
	mythred.detach();
    return 0;
}

指標在detach中絕對有問題,傳引用也是傳的複製。

class A {
public:
	A() { cout << "建構函式執行" << endl; }
	~A() { cout << "解構函式執行" << endl;  }
	A(const A &b) { cout << "拷貝建構函式執行" << endl; }
};
void myprint(int i, const A &a)
{
	cout << i << endl;
	cout << &a << endl;
}
int main()
{
	int m=1;
	int &n = m;
	A a;
	std::thread mythred(myprint, n, a);
	mythred.detach();
    return 0;
}

在這裡插入圖片描述

其中,傳已有變數的時候,A的解構函式只執行了一次。

class A {
public:
	A() { cout << "建構函式執行" << endl; }
	~A() { cout << "解構函式執行" << endl;  }
	A(const A &b) { cout << "拷貝建構函式執行" << endl; }
};
void myprint(int i, const A &a)
{
	cout << i << endl;
	cout << &a << endl;
}
int main()
{
	int m=1;
	std::thread mythred(myprint, m, A(a));
	mythred.detach();
    return 0;
}

在這裡插入圖片描述
所以,要傳物件得使用臨時物件。因為臨時物件是在主執行緒中建立的。

(1)若傳的是簡單引數,直接值傳遞,不要用引用。
(2)如果傳遞的是類物件,避免隱式型別轉換。然後在函式引數裡面,採用引用傳參,否則,還會多一次拷貝構造。
所以,detach()有什麼好。

執行緒ID:get.id()

class A {
public:
	mutable int i;
	A(int j):i(j) { cout <<"i="<<i<< "建構函式執行" << "ID=" << std::this_thread::get_id() << endl; }
	~A() { cout << "解構函式執行" << endl;  }
	A(const A &b):i(b.i) { cout << "i=" << i << "拷貝建構函式執行" << "ID=" << std::this_thread::get_id() << endl; }
};
void myprint( const A &a)
{
	a.i = 100;
	cout <<"\t\tID="<<std::this_thread::get_id()<< endl;
}
int main()
{
	A a(10);
	std::thread test(myprint, a);
	test.join();
    return 0;
}

即時傳入的是引用,但是也不會修改源物件的值,因為修改的地址不同,為了資料的安全考慮,往執行緒傳遞類型別,編譯器會統一按照拷貝的方式。

std::ref :傳遞物件,而不是拷貝。

class A {
public:
	mutable int i;
	A(int j):i(j) { cout <<"i="<<i<< "建構函式執行" << "ID=" << std::this_thread::get_id() << endl; }
	~A() { cout << "解構函式執行" << endl;  }
	A(const A &b):i(b.i) { cout << "i=" << i << "拷貝建構函式執行" << "ID=" << std::this_thread::get_id() << endl; }
};
void myprint(A &a)
{
	a.i = 100;
	cout <<"\t\tID="<<std::this_thread::get_id()<< endl;
}
int main()
{
	A a(10);
	std::thread test(myprint, std::ref(a));
	test.join();
    return 0;
}

在這裡插入圖片描述

std::move() 智慧指標線上程中的傳遞

class A {
public:
	mutable int i;
	A(int j):i(j) { cout <<"i="<<i<< "建構函式執行" << "ID=" << std::this_thread::get_id() << endl; }
	~A() { cout << "解構函式執行" << endl;  }
	A(const A &b):i(b.i) { cout << "i=" << i << "拷貝建構函式執行" << "ID=" << std::this_thread::get_id() << endl; }
};
void myprint(unique_ptr<A>a)
{
	a->i = 100;
	cout <<"\t\tID="<<std::this_thread::get_id()<< endl;
}
int main()
{
	unique_ptr<A> a(new A(10));
	std::thread test(myprint, std::move(a));
	test.join();
    return 0;
}

而且絕對不能detach()。

用成員函式作為執行緒函式。