来自另一个线程的线程中断

时间:2014-04-20 22:24:29

标签: c++ multithreading

我正在使用类似的东西创建9个线程(所有线程都将处理无限循环)

void printStr();

thread func_thread(printStr);
void printStr() {

    while (true) {
        cout << "1\n";
        this_thread::sleep_for(chrono::seconds(1));
    }

}

我还创建了第10个线程来控制它们。我如何从我的第10个停止或杀死这9个​​线程中的任何一个?或建议另一种机制。

3 个答案:

答案 0 :(得分:2)

永远不适合直接杀死一个线程,你应该向线程发送一个信号告诉它自己停止。这样可以清理并正确完成。

您使用的机制由您决定,具体取决于具体情况。它可以是在线程内定期检查的事件或状态。

答案 1 :(得分:2)

您可以使用例如atomic boolean:

#include <thread>
#include <iostream>
#include <vector>
#include <atomic>
using namespace std;

std::atomic<bool> run(true);

void foo()
{
  while(run.load(memory_order_relaxed)) 
  { 
    cout << "foo" << endl;
    this_thread::sleep_for(chrono::seconds(1));
  }
}

int main()
{
  vector<thread> v;
  for(int i = 0; i < 9; ++i)
    v.push_back(std::thread(foo));

  run.store(false, memory_order_relaxed);
  for(auto& th : v)
    th.join();

  return 0;
}

编辑(回复您的评论):您还可以使用受互斥锁保护的互变量。

#include <thread>
#include <iostream>
#include <vector>
#include <mutex>

using namespace std;

void foo(mutex& m, bool& b)
{
  while(1)
  { 
    cout << "foo" << endl;
    this_thread::sleep_for(chrono::seconds(1));

    lock_guard<mutex> l(m);
    if(!b)
      break;
  }
}

void bar(mutex& m, bool& b)
{
  lock_guard<mutex> l(m);
  b = false;
}

int main()
{
  vector<thread> v;
  bool b = true;
  mutex m;

  for(int i = 0; i < 9; ++i)
    v.push_back(thread(foo, ref(m), ref(b)));

  v.push_back(thread(bar, ref(m), ref(b)));

  for(auto& th : v)
    th.join();

  return 0;
}

答案 2 :(得分:2)

std :: thread对象是不可中断的。您将不得不使用另一个线程库,如boost或pthreads来完成您的任务。请注意杀死线程是危险的操作。

为了说明如何使用cond_wait和cond_signal在pthread中解决此问题,在主要部分中,您可以创建另一个名为monitor thread的线程,它将继续等待来自9个线程之一的信号。

pthread_mutex_t monMutex;////mutex 
pthread_cond_t condMon;////condition variable

创建线程:

pthread_t *threads = (pthread_t*) malloc (9* sizeof(pthread_t)); 
for (int t=0; t < 9;t++)
            {
                argPtr[t].threadId=t;
                KillAll=false;
                rc = pthread_create(&threads[t], NULL, &(launchInThread), (void *)&argPtr[t]);
                if (rc){
                    printf("ERROR; return code from pthread_create() is %d\n", rc);
                    exit(-1);
                }

            }

创建监控线程:

  monitorThreadarg.threadArray=threads;//pass reference of thread array to monitor thread
  monitorThreadarg.count=9;
            pthread_t monitor_thread;
            rc= pthread_create(&monitor_thread,NULL,&monitorHadle,(void * )(&monitorThreadArg));
                if (rc){
                    printf("ERROR; return code from pthread_create() is %d\n", rc);
                    exit(-1);
            }

然后等待9个线程并监视线程:

for (s=0; s < 9;s++)
        {
                pthread_join(threads[s], &status);
        }

            pthread_cond_signal(&condMon);// if all threads finished successfully then signal monitor thread too 
            pthread_join(monitor_thread, &status);
            cout << "joined with monitor thread"<<endl;

监视器功能如下:

void* monitorHadle(void* threadArray)
{
pthread_t* temp =static_cast<monitorThreadArg*> (threadArray)->threadArray;
int number =static_cast<monitorThreadArg*> (threadArray)->count;
pthread_mutex_lock(&monMutex);
mFlag=1;//check so that monitor threads has initialised
pthread_cond_wait(&condMon,&monMutex);// wait for signal 
pthread_mutex_unlock(&monMutex);
void * status;
if (KillAll==true)
{
printf("kill all \n");
for  (int i=0;i<number;i++)
{
    pthread_cancel(temp[i]);
}
}

}

将在9个线程上启动的功能应该是这样的:

  void launchInThread( void *data)
  {
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

    while(1)
        {
            try 
            {
                throw("exception whenever your criteria is met");

            }
            catch (string x)
            {
                cout << "exception form  !! "<< pthread_self() <<endl;
                KillAll=true;
                while(!mFlag);//wait till monitor thread has initialised
                pthread_mutex_lock(&monMutex);
                pthread_cond_signal(&condMon);//signail monitor thread
                pthread_mutex_unlock(&monMutex);
                pthread_exit((void*) 0);
            }
        }
 }

请注意,如果你不放:          thread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL); 在启动你的线程后,你的线程将不会在thread_cancel调用上终止。 在取消线程之前,必须清理所有数据。