2016-09-22 8 views
1

Я использую библиотеку потоков cpp. У меня есть родительский поток T1, у которого есть дочерний поток T2. T2 будет пропускать только некоторые элементы и выполнять некоторую обработку. Мне нужно приостановить и возобновить T2 из T1, используя вызовы функций из T1. 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 
} 

Предполагая, что возвращаемые типы функций являются недействительными.

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 ; 
} 
Смежные вопросы