當前位置:首頁 » 編程軟體 » qt多線程編程

qt多線程編程

發布時間: 2022-10-21 11:29:50

1. Qt多線程編程中子線程如何調用主線程中的成員變數

我提供兩種比較簡單的解決方案
創建一個Receiver的QObject, 該對象必須生存在你繼承的線程中
要麼給該對象構造對應的信號, 然後與你主線程窗體進行Connect, 一般來說是Queue的Connection
然後在子線程只要Emit你所實現的信號即可

或者用postEvent來解決, 自定義一種Event, 然後持有主線程窗體對象, 然後PostEvent給主線程窗體對象

2. QT多線程問題:子線程中的變數如何傳遞給主線程

public int _CurrentThread;

//form1_load中的,啟動線程的代碼在這里。
private void Form1_Load(object sender, EventArgs e)
{
//設置最大線程數
int MaxThread = 5;

//獲取需要完成的任務列表
OleDbConnection AccessConn = AccessMole.Conn("D:\\Flying Co\\flying.mdb");
string sql = "select * from ty_task where bay_flag=" + false + " order by bay_id asc";

OleDbCommand comm = new OleDbCommand(sql, AccessConn);
OleDbDataReader list = comm.ExecuteReader();

while (list.Read())
{
ContentParse Spider = new ContentParse();

//如果當前活動線程超過最大線程數,線程休眠
if (Spider.CurrentThread> MaxThread)
{
Thread.Sleep(2000);
}
else
{
//init
Spider.Url = list["bay_task"].ToString();

//啟動一個線程
Thread SpiderThread = new Thread(new ThreadStart(Spider.execute));
SpiderThread.Start();
MessageBox.Show(Spider.CurrentThread.ToString());

//任務設置為已處理
sql = "update ty_task set bay_flag=" + true + " where bay_id=" + list["bay_id"].ToString();
AccessMole.Execute(AccessConn, sql);
}
}

list.Close();
AccessMole.DisConn(AccessConn);
}

//線程啟動的是這個類的方法
class ContentParse
{
private string _Url;

//設置任務參數
public string Url
{
set
{
_task = value;
}
}

public void execute()
{

//活動線程數加1
Interlocked.Increment(ref _CurrentThread);

//中間處理任務的代碼省略

//該線程完成,活動線程減1
Interlocked.Decrement(ref _CurrentThread);
}

我現在糾結的就是這個Interlocked.Increment(ref _CurrentThread);應該是開一個線程就要加1的對吧?
但是我在form1中間用 MessageBox.Show(Spider.CurrentThread.ToString());,總是0噢

3. 各位QT大俠: QT多線程編程的時候,怎麼把次線程處理好的數據實時的顯示到ui上去

Qt上要求界面處理一般需要在主線程中完成。
所以最好把次線程中的數據緩沖區放到主線程中:
1、一種方式可以進行數據拷貝,但肯定效率低了。
2、另一種方式是直接將數據緩沖區放到主線程中,然後在主線程中處理讀取數據槽。但這樣可能主線程壓力大,機器配置不能太低。
3、直接在主線程中訪問次線程的數據並刷新界面,不過這處理起來復雜(需要手工同步),容易出錯。
4、將TableWidget指針傳入次線程中,直接在次線程中對其進行操作並發送刷新信號。這種方式未經驗證,感覺可能性不大:一方面指針容易走空,另一方面就是前面說的限制在主線程中對接面進行處理。不過所說的「處理」可能並不包括刷新數據吧。
期待樓主進行驗證,並展示結果。(或者樓主可以將UDP試驗項目發送給我,讓我試試,QQ:956693152,謝謝!)

4. Qt多線程繪制問題Cannot make QOpenGLContext current in a different thread

首先,創建QApplication實例前先開啟Qt::AA_,有多個context的話還可以考慮開啟Qt::AA_ShareOpenGLContexts。
其次,QOpenGLContext需要切換到使用線程才可以在那個線程make current,只需要調用其moveToThread即可。當然,context在多個線程間使用需要自行進行同步。

5. 如何對Qt中多線程系列進行限制和控制

淺析 Qt中多線程系列之線程初體驗上篇 寫了個線程的創建到運行的過程,可這還沒完,線程創建完了之後必須要對其進行限制和控制,我們就是線程的監護人,不能說任由它自由,得對它進行合理約束。接下來我們講線程的控制部分,
1、線程休眠
想像一下一種情形,日常用的電腦,如果我們需要離開一段時間,那麼可能會將它暫時休眠一下,為了節約用電,也響應一下環境保護,別忘了現在都講低炭生活。那麼線程其實也一樣,如果一個線程暫時不需要用到,我們可以先讓它睡會,其目的也是為了讓它暫時不要佔用資源,主要是一個cpu時間片的佔用問題。

對於線程的休眠,只要簡單調用 Qthread 的sleep ,msleep或者usleep 方法就可以了,注意這三個方法都是Static Protected的,這意味著你只能在繼承類里做這個動作,它們差別僅是時間單位不同而已。
程序方面我們盡量簡單點,能看清本質就可以了,在Qthread 派生類的Run方法裡面用下
1. void CThread::run()
2. {
3. for(int i=1;i<=10000;i++)
4. {
5. qDebug()<<i;
6. sleep(1); //請不要那麼快,睡一下再往下執行
7. }
8. }

2、線程喚醒
既然有線程的休眠,那就有喚醒。如果你已經和線程說 Sleep 10秒吧,突然人家睡到一半的時候,你又改變主意想讓它醒過來,這里我要抱歉的說聲是沒辦法的,它就像豬一樣,沒到時間是不會醒的。比較合適的方案就是線程同步能夠解決這樣的問題,這個放到下一篇 線程的同步[1/2] 的時候再說.只要記住sleep是強制休眠就可以,但現在沒辦法提供強制喚醒的辦法.
3、線程關閉
如果一個線程運行完了它會自己結束自己的生命。可很多情況不是這么簡單,一個線程跑到中間的時候由於某種特殊原因,就想它中止。
(1)線程中止方式
中止有兩種方式 強制中止和 優雅中止,這用詞可能有點不恰當,先這么說著。在說明這兩種方式之前,有必要詳細說一下線程關閉的時候它到底幹了什麼。
線程關閉的時候,OS會移除這個線程,這部分對我們是透明的,詳細的說明還得參閱操作系統的有關書籍,接著線程中分配的堆棧信息將一並清除,但是如果是堆上分配的信息,得由你負責自己清除,因為堆是由進程持有的,它的生命周期和線程沒關系。
(2)強制中止:
簡單的調用Qthread 的方法terminate就可以進行強制中止,可這將會帶來很多災難性的後果。最為嚴重的就是一個堆內存泄露的問題,線程強制被中止,根本沒法來得及做清理工作,即使你的線程中有執行到最後清理堆內存,可它沒來得及執行
比如以下一段代碼
1. void CThread::run()
2. {
3. int *c = new int;
4. for(int i=1;i<=10000;i++)
5. {
6. qDebug()<<i;
7. }
8. //clean
9. delete c;
10. }

想像一下線程還沒執行 到 delete c;的時候你就發出了terminate,不幸的事就發生了,由此得出結論我們應該盡最大限度避免去使用。

(3)優雅的中止:

那麼怎麼優雅的關閉線程呢?我們應該通知線程,讓線程自己去接手關閉,各自關注自己所需的事,就都能做得更好,一手抓就會帶來很多問題

那麼怎麼通知線程呢? 一般會採用以下的步驟
1.在Qthread中派生類 定義一個公用方法出來 供中止時調用,比如stop()
2.調用者 直接 調用stop方法
3.派生類stop方法 ,設置 中止標志,一般就是bool成員
4.run方法 運行的時候,檢查bool成員,判斷是否需要退出進程,最後做清理工作
1. //CThread.h
2. #ifndef CTHREAD_H
3. #define CTHREAD_H
4. #include <QThread>
5. class CThread : public QThread
6. {
7. public:
8. CThread();
9. ~CThread();
10. void stop();
11. protected:
12. void run();
13. private:
14. bool mStop;
15. };
16. #endif // CTHREAD_H
17.
18. //CThread.cpp
19. #include <QDebug>
20. #include "CThread.h"
21. CThread::CThread():QThread(),mStop(false)
22. {
23. }
24. CThread::~CThread()
25. {
26. stop();
27. }
28. void CThread::run()
29. {
30. int *c = new int;
31. for(int i=1;i<=10000;i++)
32. {
33. if (mStop) // determine to exit the loop
34. {
35. break;
36. }
37. qDebug()<<i;
38. sleep(1);
39. }
40. //clean up
41. delete c;
42. }
43. void CThread::stop()
44. {
45. mStop = true;
46. wait();
47. }

6. qt 怎麼使用多線程遍歷文件夾

一、Qt遍歷文件夾下一層的文件:
方式1:
void ImageTree::addFolderImages(QString path)
{
//判斷路徑是否存在
QDir dir(path);
if(!dir.exists())
{
return;
}
dir.setFilter(QDir::Files | QDir::NoSymLinks);
QFileInfoList list = dir.entryInfoList();
int file_count = list.count();
if(file_count <= 0)
{
return;
}
QStringList string_list;
for(int i=0; i
{
QFileInfo file_info = list.at(i);
QString suffix = file_info.suffix();
if(QString::compare(suffix, QString("png"), Qt::CaseInsensitive) == 0)
{
QString absolute_file_path = file_info.absoluteFilePath();
string_list.append(absolute_file_path);
}
}
}
分析:遍歷文件的下一層,對於系統而言包括:文件夾、文件、快捷方式,使用setFilter即可過濾。通過entryInfoList則可以獲取過濾後所得到的文件夾下的文件信息列表,遍歷文件通過操作QFileInfo可得到所需的文件詳細信息(大小、類型、後綴等)。

7. Qt如何進行創建多線程

在Qt中使用多線程,目前就我使用過的有兩種,一是子類化QThread,重寫run函數,在run函數里實現自己的代碼,這一部分代碼通常是比較耗時,或者乾脆直接阻塞的。比如一個while循環,設置一個標志,判斷循環結束。
這樣的例子在網上有很多,就不寫了。

這樣寫的話,會有一些東西需要了解。
子類化QThread的方法,只有run函數裡面的內容是執行在子線程里的,其他的部分,比如槽函數什麼的還是在主線程里執行(假設是在主線程開啟的該子線程)。

還有一種方法,是子類化QObject,新建一個線程,然後使用MoveToThread把這個類的對象移到新建的線程中,這種做法使得它所有的槽函數都是執行在新開辟的線程裡面。

如果直接(QObject對象).abc()的話,這個成員函數是在主進程內執行,可能會出現"QObject::killTimer: timers
cannot be stopped from another thread"的運行錯誤。

使用第二種方法的話,貌似會遇到這樣的問題:如果在一個槽函數中把子線程阻塞,其他的槽函數無法接受來自主線程

8. qt中connect 函數多線程怎麼設置

項目中遇到了關於多線程編程問題
Class obj中有一個QTimer。線程A和線程B都有機會重啟這個QTimer。
然而,在QT文檔中QTimer並不是一個線程安全的類,因此就出現了怎樣保證跨線程調用的安全性

首先,obj是是有線程概念的,它必須屬於一個特定線程的(當然也可以使用moveToThread將它放入另外一個線程中,所有繼承自QObject都有一個threadid的屬性,用來標明此對象所屬線程)

9. qt多線程編程裡面怎麼設置線程數

我學習QT的線程模塊沒多久。實現方案是繼承QThread類,編寫一個新的Thread線程類。
然後在主進程中要調用的時候就創建一個新的Thread並調用run函數啟動線程。可以用數組存放這些thread,這樣可方便主線程對這些線程的管理。

熱點內容
破解exe加密視頻 發布:2025-05-17 11:23:41 瀏覽:976
我的世界伺服器圈太大了怎麼辦 發布:2025-05-17 11:15:21 瀏覽:614
便宜的免費雲伺服器 發布:2025-05-17 11:08:50 瀏覽:776
中國頂級dhcp解析伺服器地址 發布:2025-05-17 11:06:27 瀏覽:34
php轉義html 發布:2025-05-17 11:04:00 瀏覽:567
鋼筋籠加密區規范 發布:2025-05-17 10:59:50 瀏覽:4
我的世界網易手機版主播伺服器房號 發布:2025-05-17 10:40:59 瀏覽:227
豎編譯 發布:2025-05-17 09:56:08 瀏覽:229
編程畫飛機 發布:2025-05-17 09:54:03 瀏覽:803
手機如何解鎖密碼屏幕鎖怎麼刪除 發布:2025-05-17 09:52:04 瀏覽:125