2016-09-22 90 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 ; 
}