Qt線程
使用Qt開發多線程應用,這里有一篇必看的官網博客:You are doing it wrong,文章講了QThread使用時常犯的錯誤。總結下來,QThread的正確使用思路有兩種:
- 繼承QThread,重新實現run(),將需要次線程執行的代碼寫入run()即可。
- 繼承QObject實現功能,使用線程時創建一個QThread對象,將QObject對象通過moveToThread()移入該線程。
update:今天看Qt5的文檔,發現官方文檔已經添加了示例代碼,直接看這個就可以了。
Qt并發
并發是更高層的接口,可以不去操作底層的線程,也不需要關心信號和槽所在的線程,比較容易上手。Qt Concurrent使用方法很簡單,如果是普通函數,調用方式為:
QFuture<T> QtConcurrent::run(Function function, ... )
如果是類的成員函數,需要傳入對象指針。比如上面的例子,相當于默認傳入了一個全局指針:
QtConcurrent::run(QThreadPool::globalInstance(), function, ...);
C++ 11的異步和線程
對比一下C++標準的異步實現:
#include <iostream>
#include <future>
#include <thread>
std::future<int> ft;
void async_func(){
// 開始異步執行
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 {
// 等一秒查一下狀態
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);
}
下面是線程的簡單示例(互斥鎖):
#include <thread>
#include <mutex>
#include <chrono>
std::mutex mlock;
void func()
{
mlock.lock(); // 可以去掉鎖后觀察區別
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();
}