2014-02-27 116 views
0

我有一個叫做write()的C++函數,它應該在用戶HDD上寫入大量的字節。這通常需要超過30秒,所以我想讓用戶能夠從GUI(使用Qt創建)Abort operation用C++結束函數

所以我有按鈕generate_button。當這個按鈕是clicked()時,我想要結束這個功能,無論它在哪裏進展。

我想過線程,但我不確定。你能幫我建議嗎?

回答

2

我可能會使用一個線程。檢查變量以查看操作是否已被取消應該非常簡單。

使用互斥鎖來鎖定對取消變量的訪問。這將確保它以適當的方式讀取和寫入多個線程。 Another option is if you are using C++11 use an atomic variable.

將您的大寫分成更小的塊。應該工作8到64千字節。寫入每個塊後,檢查你的取消變量,如果設置,退出線程。

+0

是的,我正在使用C++ 11。我會接受你的答案,但你能寫一些代碼來演示原子變量嗎? – Victor

+0

@Victor:我偷走了來自Zac的原子的參考鏈接並將其放入我的答案中。 –

2

將實際執行寫入的代碼放在工作線程中。有一個共享變量(一個是原子的,或者是一個互斥體保護的變量)。讓工作線程每次迭代檢查其值。如果用戶按下「中止」按鈕,爲變量設置值。

應該如果這是一個長時間運行的操作使用線程。

由於您使用的是C++ 11,因此std::atomic<bool>可能會很好地爲您服務。

+0

那麼,在Windows中,通過使用帶有寫入和PeekMessage的循環,可以在沒有線程的情況下完成。 Qt可能有類似的東西。 –

+0

@ZanLynx即使您要使用OverlappedIO功能,仍然會在下面爲您創建一個線程。真正做到沒有單獨線程的唯一方法就是做一些響應特定消息(例如WM_IDLE)的東西,這會變得非常混亂。 –

+0

@ZanLynx使用這樣的解決方案有很多不必要的障礙。特別是對於今天的硬件(多核系統),創建單獨的工作線程是更好的解決方案。 –

1

Threaded保證您將具有響應式GUI。但是以這種方式使用線程有一個學習曲線。

執行此操作的無線方法是在您的例程中寫入GUI線程中的硬盤,但給GUI線程留出時間以保持響應。

QObject::connect(my_cancel_button, SIGNAL(clicked()), file_writer, SLOT(setCanceled())); 

// open file for writing 
QFile file("filename.txt"); 
file.open(//...);// 

while(still_have_data_to_write && !canceled) 
{ 
    write(<1 MB of data>); // or some other denomination of data 

    qApp->processEvents();// allows the gui to respond to events such as clicks on buttons 

    // update a progress bar... using a counter as a ratio of the total file size 
    emit updateProgressBar(count++); 
} 

if(canceled) 
{ 
    file.close(); 
    // delete the partial file using QDir 
} 

希望有幫助。

+0

我會盡快嘗試一種方法,但我想我會保留我已經接受的答案,因爲我的庫旨在以純C++工作,沒有任何其他庫(正如您在此提到的關於Qt的內容) – Victor