題目:子線程循環 10 次,接着主線程循環 100 次,接着又回到子線程循環 10 次,接着再回到主線程又循環 100 次,如此循環50次,試寫出代碼promise
子線程與主線程必有一個知足條件(flag == num),不知足條件的那個線程不可能獲取unique_lock(會在wait中釋放),只有知足條件的線程才能獲取鎖,執行程序安全
mutex m;//保護條件的互斥訪問 condition_variable cond;//條件變量 int flag = 10;//條件 void fun(int num) { for (int i = 0; i<50; i++) { unique_lock<mutex> lk(m);//A unique lock is an object that manages a mutex object with unique ownership in both states: locked and unlocked. while (flag != num) cond.wait(lk);//在調用wait時會執行lk.unlock() for (int j = 0; j<num; j++) cout << j << " "; cout << endl; flag = (num == 10) ? 100 : 10; cond.notify_one();//被阻塞的線程喚醒後lk.lock()恢復在調用wait前的狀態 } } int main() { thread child(fun, 10); fun(100); child.join(); system("pause"); return 0; }
題目:編寫一個程序,開啓3個線程,這3個線程的ID分別爲A、B、C,每一個線程將本身的ID在屏幕上打印10遍,要求輸出結果必須按ABC的順序顯示;如:ABCABC….依次遞推。多線程
mutex m; condition_variable cond; int loop = 10; int flag = 0; void func(int id) { for (int i = 0; i < loop; ++i) { unique_lock<mutex> lk(m); while (flag != id) cond.wait(lk); cout << static_cast<char>('A' + id) << " "; flag = (flag + 1) % 3; cond.notify_all(); } } void main() { thread A(func, 0); thread B(func, 1); func(2); cout << endl; A.join(); B.join(); system("pause"); }
題目(google筆試題):有四個線程一、二、三、4。線程1的功能就是輸出1,線程2的功能就是輸出2,以此類推.........如今有四個文件ABCD。初始都爲空。現要讓四個文件呈以下格式:
A:1 2 3 4 1 2....
B:2 3 4 1 2 3....
C:3 4 1 2 3 4....異步
D:4 1 2 3 4 1....oop
mutex m; condition_variable cond; int loop = 10; int flag; void func(int num) { for (int i = 0; i < loop; ++i) { unique_lock<mutex> lk(m); while (num != flag) cond.wait(lk); cout << num + 1 << " "; flag = (flag + 1) % 4; cond.notify_all(); } } void main(int argc,char *argv[]) { flag = atoi(argv[1]); thread one(func, 1); thread two(func, 2); thread three(func, 3); func(0); one.join(); two.join(); three.join(); cout << endl; system("pause"); }
讀者寫者問題this
這也是一個很是經典的多線程題目,題目大意以下:有一個寫者不少讀者,多個讀者能夠同時讀文件,但寫者在寫文件時不容許有讀者在讀文件,一樣有讀者讀時寫者也不能寫。google
class rwlock { private: mutex _lock; condition_variable _wcon, _rcon; unsigned _writer, _reader; int _active; public: void read_lock() { unique_lock<mutex> lock(_lock); ++_reader; while (_active < 0 || _writer > 0) _rcon.wait(lock); --_reader; ++_active; } void write_lock() { unique_lock<mutex> lock(_lock); ++_writer; while (_active != 0) _wcon.wait(lock); --_writer; _active = -1; } void unlock() { unique_lock<mutex> lock(_lock); if (_active > 0) { --_active; if (_active == 0) _wcon.notify_one(); } else { _active = 0; if (_writer > 0) _wcon.notify_one(); else if (_reader > 0) _rcon.notify_all(); } } rwlock() :_writer(0), _reader(0), _active(0) { } }; void t1(rwlock* rwl) { while (1) { cout << "I want to write." << endl; rwl->write_lock(); cout << "writing..." << endl; this_thread::sleep_for(chrono::seconds(5)); rwl->unlock(); this_thread::sleep_for(chrono::seconds(5)); } } void t2(rwlock* rwl) { while (1) { cout << "t2-I want to read." << endl; rwl->read_lock(); cout << "t2-reading..." << endl; this_thread::sleep_for(chrono::seconds(1)); rwl->unlock(); } } void t3(rwlock* rwl) { while (1) { cout << "t3-I want to read." << endl; rwl->read_lock(); cout << "t3-reading..." << endl; this_thread::sleep_for(chrono::seconds(1)); rwl->unlock(); } } int main() { rwlock* rwl = new rwlock(); thread th1(t1, rwl); thread th2(t2, rwl); thread th3(t3, rwl); th1.join(); th2.join(); th3.join(); system("pause"); return 0; }
線程安全的queueatom
STL中的queue是非線程安全的,一個組合操做:front(); pop()先讀取隊首元素而後刪除隊首元素,如果有多個線程執行這個組合操做的話,可能會發生執行序列交替執行,致使一些意想不到的行爲。所以須要從新設計線程安全的queue的接口。spa
template<typename T> class threadsafe_queue { private: mutable std::mutex mut; std::queue<T> data_queue; std::condition_variable data_cond; public: threadsafe_queue() {} threadsafe_queue(threadsafe_queue const& other) { std::lock_guard<std::mutex> lk(other.mut); data_queue = other.data_queue; } void push(T new_value)//入隊操做 { std::lock_guard<std::mutex> lk(mut); data_queue.push(new_value); data_cond.notify_one(); } void wait_and_pop(T& value)//直到有元素能夠刪除爲止 { std::unique_lock<std::mutex> lk(mut); data_cond.wait(lk, [this] {return !data_queue.empty(); }); value = data_queue.front(); data_queue.pop(); } std::shared_ptr<T> wait_and_pop() { std::unique_lock<std::mutex> lk(mut); data_cond.wait(lk, [this] {return !data_queue.empty(); }); std::shared_ptr<T> res(std::make_shared<T>(data_queue.front())); data_queue.pop(); return res; } bool try_pop(T& value)//無論有沒有隊首元素直接返回 { std::lock_guard<std::mutex> lk(mut); if (data_queue.empty()) return false; value = data_queue.front(); data_queue.pop(); return true; } std::shared_ptr<T> try_pop() { std::lock_guard<std::mutex> lk(mut); if (data_queue.empty()) return std::shared_ptr<T>(); std::shared_ptr<T> res(std::make_shared<T>(data_queue.front())); data_queue.pop(); return res; } bool empty() const { std::lock_guard<std::mutex> lk(mut); return data_queue.empty(); } };
題目:編寫程序完成以下功能:.net
1)有一int型全局變量g_Flag初始值爲0
2) 在主線稱中起動線程1,打印「this is thread1」,並將g_Flag設置爲1
3) 在主線稱中啓動線程2,打印「this is thread2」,並將g_Flag設置爲2
4) 線程序1須要在線程2退出後才能退出
5) 主線程在檢測到g_Flag從1變爲2,或者從2變爲1的時候退出
atomic<int> flag(0); void worker1(future<int> fut) {//線程1 printf("this is thread1\n"); flag = 1; fut.get();//線程1阻塞至線程2設置共享狀態 get等待異步操做結束並返回結果 printf("thread1 exit\n"); } void worker2(promise<int> prom) {//線程2 printf("this is thread2\n");//C++11的線程輸出cout沒有boost的好,仍是會出現亂序,因此採用printf,有點不爽 flag = 2; prom.set_value(10);//線程2設置了共享狀態後,線程1纔會被喚醒 printf("thread2 exit\n"); } //利用promise future來控制線程退出的次序 int main() { promise<int> prom; future<int> fut = prom.get_future(); thread one(worker1, move(fut));//注意future和promise不容許拷貝,可是具有move語義 thread two(worker2, move(prom)); while (flag.load() == 0);
///將本線程從調用線程中分離出來,容許本線程獨立執行 one.detach(); two.detach(); //exit(1);//主線程到這裏退出 printf("main thread exit\n"); system("pause"); return 0; }
http://blog.csdn.net/liuxuejiang158blog/article/details/22300081