2016-09-22 91 views
1

我正在使用cpp線程庫。我有一個父線程T1,它有一個子線程T2。 T2只會循環一些項目並做一些處理。我需要暫停並使用T1的函數調用從T1恢復T2。 T1和T2屬於同一類。當一個特定的事件到達T1時,我需要這個來停止處理數據;請不要建議任何其他線程實現庫。從cpp的父線程中暫停並恢復線程

C::t2_func{ 
     for(int i=0;i<data.size();i++) 
     process_data(data[i]); 
    } 
    C::spawn(){ 
     t2 = std::make_unique<std::thread>(std::bind(&C::t2_func, this)); 
    } 
    C::pause(){ 
     //pause t2 
    } 
    C::resume(){ 
     //resume t2 
    } 

回答

2
bool pause=false; 
std::condition_variable cv; 
std::mutex m; 
void C::t2_func(){ 
    for(int i=0;i<data.size();i++){ 
    while(pause){ 
     std::unique_lock<std::mutex> lk(m); 
     cv.wait(lk); 
     lk.unlock(); 
    } 
    process_data(data[i]); 
    } 
} 

void C::spawn(){ 
    t2 = std::make_unique<std::thread>(std::bind(&C::t2_func, this)); 
} 
void C::pause(){ 
    //pause 
    std::lock_guard<std::mutex> lk(m); 
    pause=true; 
} 
void C::resume(){ 
    std::lock_guard<std::mutex> lk(m); 
    pause=false; 
    cv.notify_one(); 
    //resume t2 
} 

假設函數的返回類型爲void。

1

您不能在外部暫停線程。但是一個線程可以暫停。考慮使用std::condition_variable和布爾標誌is_paused。然後在每次迭代的工作線程中,您鎖定一個互斥鎖,檢查線程是否應該暫停,是否應該等待條件變量,直到is_paused重置爲false。並且在主線程中鎖定互斥鎖,更改is_paused並通知條件變量。

0

很多人在論壇上問過一個線程是否可以暫停和恢復或取消,不幸的是目前我們不能。但是如果有這種可怕的必要性,我有時候會這樣做。使您的功能增量(細粒度),以便它可以連續執行,您可以在下面的簡單示例中進行操作,如下所示:

void main() 
{ 
enum tribool { False,True,Undetermine}; 

bool running = true; 
bool pause = false; 

std::function<tribool(int)> func = [=](long n) 
    { 
    long i; 

    if (n < 2) return False; 
    else 
    if (n == 2) return True; 

    for (i = 2; i < n; i++) 
    { 
     while (pause) 
     { 
      if (!pause) break; 
      if (!running) return Undetermine; 
     } 
     if (n%i == 0) return False; 
    } 
    return True; 
    }; 

    std::future<tribool> fu = std::async(func,11); 

    pause = true; //testing pause 
    pause = false; 

    auto result = fu.get(); 
    if (result == True) std::cout << " Prime"; 
    else 
    if (result == False) std::cout << " Not Prime"; 
    else 
    std::cout << " Interrupted by user"; 

    return ; 
}