2016-09-22 10 views
1

私はcppスレッドライブラリを使用しています。私は子スレッドT2を持つ親スレッドT1を持っています。 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にリセットされるまで条件変数を待ちます。そしてあなたのメインスレッドでmutexをロックし、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 ; 
} 
関連する問題