日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

C++線程之thread詳解_C 語言

作者:早睡的葉子 ? 更新時間: 2022-05-19 編程語言

1.創建線程

直接初始話thread類對象進行創建線程,創建線程后調用join()方法,讓主線程等待子線程完成工程。

#include 
#include 
void thread_function()
{
    std::cout << "thread function\n";
}
int main()
{
    std::thread t(&thread_function);   // t starts running
    std::cout << "main thread\n";
    t.join();   // main thread waits for the thread t to finish
    return 0;
}

2.守護線程

我們可以調用detach()方法,將線程變為守護線程,完成線程和主線程的分離。一旦線程分離,我們不能強迫它再次加入主線程,再次調用join()方法會報錯的。

一旦分離,線程應該永遠以這種方式存在。調用join()函數之前可以使用函數joinable()檢查線程是否可以加入主線程,加強程序健壯性。

// t2.cpp
int main()
{
    std::thread t(&thread_function);
    std::cout << "main thread\n";
    if( t.joinable( ) ) 
        // t.join();
    // t.join();
    t.detach();
    return 0;
}

3. 可調用對象

線程可以調用

  • 函數指針
  • 類對象
  • lamda表達式

1.函數指針

就像之前舉例的樣子

2.類對象

#include 
#include 
class MyFunctor
{
public:
    void operator()() {
        std::cout << "functor\n";
    }
};
int main()
{
    MyFunctor fnctor;
    // 這樣是不能運行的,
    // std::thread t(fnctor);
    // 必須按照這樣進行初始話。
    // MyFunctor fnctor;  Note that we had to add () to enclose the MyFunctor(). 
    std::thread t((MyFunctor())); // it's related to the function declaration convention in C++.
    std::cout << "main thread\n";
    t.join();
    return 0;
}

3.lamda表達式

#include 
#include 
class MyFunctor
{
public:
    void operator()() {
        std::cout << "functor\n";
    }
};
int main()
{
    MyFunctor fnctor;
    // 這樣是不能運行的,
    // std::thread t(fnctor);
    // 必須按照這樣進行初始話。
    // MyFunctor fnctor;  Note that we had to add () to enclose the MyFunctor(). 
    std::thread t((MyFunctor())); // it's related to the function declaration convention in C++.
    std::cout << "main thread\n";
    t.join();
    return 0;
}

4. 傳參

傳參分為三種

1.值傳遞

2.引用傳遞

3.不復制,也不共享內存的傳參方式move()

#include 
#include 
#include 
void thread_function(std::string s)
{
    std::cout << "thread function ";
    std::cout << "message is = " << s << std::endl;
}
int main()
{
    std::string s = "Kathy Perry";
    // 1. 值傳遞
    std::thread t(&thread_function, s);
    // 2. 引用傳遞
    std::thread t(&thread_function, std::ref(s));
    // 3. 不復制,也不共享內存的傳參方式`move()
    std::thread t(&thread_function, std::move(s));
    std::cout << "main thread message = " << s << std::endl;
    t.join();
    return 0;
}

5. 線程的移動和復制

// t5.cpp
#include 
#include 
void thread_function()
{
    std::cout << "thread function\n";
}
int main()
{
    std::thread t(&thread_function);
    std::cout << "main thread\n";
    //  transfer the ownership of the thread by moving it:
    std::thread t2 = move(t);
    t2.join();
    return 0;
}

6.線程id

獲取線程的id:?this_thread::get_id()

總共有多少個線程:std::thread::hardware_concurrency()

程序

int main()
{
    std::string s = "Kathy Perry";
    std::thread t(&thread_function, std::move(s));
    std::cout << "main thread message = " << s << std::endl;
    std::cout << "main thread id = " << std::this_thread::get_id() << std::endl;
    std::cout << "child thread id = " << t.get_id() << std::endl;
    t.join();
    return 0;
}

輸出

thread function message is = Kathy Perry
main thread message =
main thread id = 1208
child thread id = 5224

7. 互斥mutex

互斥鎖可能是 C++ 中使用最廣泛的數據保護機制,但重要的是構造我們的代碼以保護正確的數據并避免接口中固有的競爭條件。互斥鎖也有自己的問題,表現為死鎖和保護太多或太少的數據

標準 C++ 庫提供了std::lock_guard類模板,它實現 了互斥鎖的RAII習慣用法。它在構造時鎖定提供的互斥鎖并在銷毀時解鎖它,從而確保始終正確解鎖鎖定的互斥鎖。

#include 
#include 
#include 
#include 
#include 
using namespace std;
// a global variable
std::listmyList;
// a global instance of std::mutex to protect global variable
std::mutex myMutex;
void addToList(int max, int interval)
{
	// the access to this function is mutually exclusive
	std::lock_guard guard(myMutex);
	for (int i = 0; i < max; i++) {
		if( (i % interval) == 0) myList.push_back(i);
	}
}
void printList()
{
	// the access to this function is mutually exclusive
	std::lock_guard guard(myMutex);
	for (auto itr = myList.begin(), end_itr = myList.end(); itr != end_itr; ++itr ) {
		cout << *itr << ",";
	}
}
int main()
{
	int max = 100;
	std::thread t1(addToList, max, 1);
	std::thread t2(addToList, max, 10);
	std::thread t3(printList);
	t1.join();
	t2.join();
	t3.join();
	return 0;
}

總結

原文鏈接:https://blog.csdn.net/sexyluna/article/details/123531927

欄目分類
最近更新