使用C++11讓多執行緒開發變得簡單
阿新 • • 發佈:2019-02-19
#include <iostream>
#include <functional>
#include <map>
#include <vector>
#include <algorithm>
#include <cstring>
#include <thread>
using namespace std;
void func(){
this_thread::sleep_for(chrono::seconds(3));
cout << "do something" << endl;
}
int main(){
thread t(func);
//t.join();//函式func會運行於執行緒物件t中,join函式會阻塞執行緒,直到執行緒函式執行結束,如果執行緒函式有返回值,返回值被忽略
//t.detach();//將執行緒和執行緒物件分離,讓執行緒作為後臺執行緒去執行,當前執行緒也不會阻塞了
//需要注意的是detach()之後就無法再和執行緒發生聯絡了,比如detach之後就不能通過join來等待執行緒執行完,執行緒何時執行完我們也無法控制了
thread t1(move(t));//執行緒移動以後,t就不存在了,這個時候就不能呼叫t.join()函數了。
//t.join();-->error
cout << t1.get_id() << endl;//獲取當前執行緒id,22644
cout << "timeout" << endl;
t1.join();
cout << t1.get_id() << endl;//獲取當前執行緒id,0,表示已經執行結束了.
cout << std::thread::hardware_concurrency() << endl;//8核
return 0;
}
#include <iostream>
#include <functional>
#include <map>
#include <vector>
#include <algorithm>
#include <cstring>
#include <thread>
#include <mutex>
using namespace std;
mutex glock;
void func(){
glock.lock();
this_thread::sleep_for(chrono::seconds(3));
cout << "do something" << endl;
glock.unlock();//加鎖封鎖操作
}
void fun(){
lock_guard<mutex> lock(glock);//出作用域自動解鎖.
cout << this_thread::get_id() << " works now" << endl;
this_thread::sleep_for(chrono::seconds(3));
cout << "do something" << endl;
}
int main(){
thread t1(fun);
thread t2(fun);
thread t3(fun);
t1.join();
t2.join();
t3.join();
return 0;
}
一個執行緒池
#include <iostream>
#include <functional>
#include <map>
#include <vector>
#include <algorithm>
#include <cstring>
#include <thread>
#include <mutex>
using namespace std;
template <class T>
class ThreadPool{
bool isFull() const {
return m_queue.size() == m_maxSize;
}
bool isEmpty() const{
return m_queue.empty();
}
public:
ThreadPool(int mSize) :m_maxSize(mSize){}
void put(const T &value){
unique_lock<mutex> locker(m_mutex);
while (isFull){
cout << "緩衝區滿了" << endl;
m_notFull.wait(locker, [this](){return !isFull()});
}
m_queue.push_back(value);
m_notEmpty.notify_one();
}
void get(const T&x){
unique_lock<mutex> locker(m_mutex);
while (isEmpty){
cout << "緩衝區為空" << endl;
m_notEmpty.wait(locker, [this](){return !is_empty()});
}
x = m_queue.pop_front();
}
bool Empty(){
std::lock_guard<mutex>locker(m_mutex);
return m_queue.empty();
}
bool Full(){
std::lock_guard<mutex>locker(m_mutex);
return m_queue.size() == m_maxSize;
}
size_t Size(){
std::lock_guard<mutex>locker(m_mutex);
return m_queue.size();
}
int count(){
std::lock_guard<mutex>locker(m_mutex);
return m_queue.size();
}
private:
condition_variable m_notEmpty;
mutex m_mutex; //互斥量
int m_maxSize; //執行緒池最大緩衝數目
list<T> m_queue;//緩衝區,緩衝佇列
};
int main(){
return 0;
}
#include <iostream>
#include <functional>
#include <map>
#include <vector>
#include <algorithm>
#include <cstring>
#include <thread>
#include <mutex>
#include <future>
#include <chrono>
using namespace std;
int main(){
promise<int>pr;
thread t([](promise<int>&p){
p.set_value_at_thread_exit(100);
}, ref(pr));
t.join();
//t.detach();必須選擇一個,否則程式會發生異常,不明白為什麼會發生異常.
future<int>f = pr.get_future();
auto i = f.get();
cout << i << endl;
packaged_task<int()> task([](){ return 7; });
thread t2(ref(task));
t2.join();
future<int> fut = task.get_future();
cout << fut.get() << endl;
return 0;
}
C++11 提供了幾種非同步呼叫的方法,都能通過std::future來獲取非同步執行的結果。
- std::promise 可以用來線上程間提供資料傳遞。std::future = std::promise.get_future()。執行緒中可以對promise賦值std::promise.set_value。賦值之後std::future.get()就會返回其他執行緒中設定的值。
promise封裝了資料和future,將資料和future繫結起來,為獲取執行緒函式中的某一個值提供便利,線上程函式中為外面傳進來的promise賦值,線上程函式執行完成以後,,就可以通過promise的get_future方法獲取該值了
#include <iostream>
#include <future>
#include <chrono>
std::promise<int> promis;
int main(int argc, const char * argv[]) {
std::thread t([](std::promise<int>& promis){
std::this_thread::sleep_for(std::chrono::seconds(10));
promis.set_value_at_thread_exit(123);
},ref(promis));
t.detach();
std::cout << "detach..." << std::endl;
std::future<int> fuResult = promis.get_future();
std::cout << fuResult.get() << std::endl;
return 0;
}
2.std::packaged_task 可以包裹一個函式, 有點類似std::function,不同之處在於這個可以通過get_future返回std::future物件來獲取非同步執行的函式結果。
包裝了一個可呼叫物件的包裝類,如function, lambda expression, bind expression 和another function object,將函式和future繫結起來,以便非同步呼叫。
#include <iostream>
#include <future>
#include <chrono>
int main(int argc, const char * argv[]) {
int y;
std::cin >> y;
std::packaged_task<int(int)> m([](int x){
std::this_thread::sleep_for(std::chrono::seconds(10));
return x + 100;
});
std::future<int> fuResult = m.get_future();
std::thread task(std::move(m),y); //給y加100,得到返回值.
task.detach();
std::cout << "detach..." << std::endl;
std::cout << fuResult.get() << std::endl;
return 0;
}
- std::async提供非同步執行的方法,std::future = std::async(…), 函式執行完成後可以通過std::future.get()獲取到執行函式的返回值
async()叫做執行緒非同步操作函式!!!
#include <iostream>
#include <future>
#include <chrono>
int main(int argc, const char * argv[]) {
std::future<int> fuResult = std::async([](){std::launch::async,
std::this_thread::sleep_for(std::chrono::seconds(1));
return 1;
});
std::cout << "detach..." << std::endl;
std::cout << fuResult.get() << std::endl;
return 0;
}
#include <iostream>
#include <future>
#include <chrono>
using namespace std;
struct Base{
void Fun()
{
cout << "it is fun" << endl;
}
};
struct Derived:Base{
using Base::Fun;//c++11新特性.
void Fun(int a){
cout << "it is fun in derived" << endl;
}
};
int main() {
Derived d;
//d.Fun();//會產生編譯錯誤
d.Fun();//這樣就不會出錯了.
return 0;
}