Qt線程
使用Qt開(kāi)發(fā)多線程應(yīng)用,這里有一篇必看的官網(wǎng)博客:You are doing it wrong栗柒,文章講了QThread使用時(shí)常犯的錯(cuò)誤∷猜伲總結(jié)下來(lái),QThread的正確使用思路有兩種:
- 繼承QThread逛钻,重新實(shí)現(xiàn)run()僚焦,將需要次線程執(zhí)行的代碼寫入run()即可曙痘。
- 繼承QObject實(shí)現(xiàn)功能芳悲,使用線程時(shí)創(chuàng)建一個(gè)QThread對(duì)象边坤,將QObject對(duì)象通過(guò)moveToThread()移入該線程芭概。
update:今天看Qt5的文檔惩嘉,發(fā)現(xiàn)官方文檔已經(jīng)添加了示例代碼,直接看這個(gè)就可以了。
Qt并發(fā)
并發(fā)是更高層的接口殿较,可以不去操作底層的線程,也不需要關(guān)心信號(hào)和槽所在的線程桩蓉,比較容易上手。Qt Concurrent使用方法很簡(jiǎn)單院究,如果是普通函數(shù),調(diào)用方式為:
QFuture<T> QtConcurrent::run(Function function, ... )
如果是類的成員函數(shù)业汰,需要傳入對(duì)象指針。比如上面的例子样漆,相當(dāng)于默認(rèn)傳入了一個(gè)全局指針:
QtConcurrent::run(QThreadPool::globalInstance(), function, ...);
C++ 11的異步和線程
對(duì)比一下C++標(biāo)準(zhǔn)的異步實(shí)現(xiàn):
#include <iostream>
#include <future>
#include <thread>
std::future<int> ft;
void async_func(){
// 開(kāi)始異步執(zhí)行
ft = std::async(std::launch::async, [](){
std::cout << "async start" <<endl;
std::this_thread::sleep_for(std::chrono::seconds(3));
return 2046;
});
}
void testAsync(){
std::future_status status;
do {
// 等一秒查一下?tīng)顟B(tài)
status = ft.wait_for(std::chrono::seconds(1));
if (status == std::future_status::deferred) {
std::cout << "deferred" << std::endl;
} else if (status == std::future_status::timeout) {
std::cout << "timeout" << std::endl;
} else if (status == std::future_status::ready) {
std::cout << "ready" << std::endl;
std::cout << ft.get() << std::endl;
}
} while(status != std::future_status::ready);
}
下面是線程的簡(jiǎn)單示例(互斥鎖):
#include <thread>
#include <mutex>
#include <chrono>
std::mutex mlock;
void func()
{
mlock.lock(); // 可以去掉鎖后觀察區(qū)別
std::cout << "in...." << std::this_thread::get_id() << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(2));
std::cout << "out..." << std::this_thread::get_id() << std::endl;
mlock.unlock();
}
void testThread(){
std::thread t1(func);
std::thread t2(func);
t1.join();
t2.join();
}