我怎么能杀的pthread是一个无限循环,从外循环? [英] How can I kill a pthread that is in an infinite loop, from outside that loop?

查看:247
本文介绍了我怎么能杀的pthread是一个无限循环,从外循环?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建一个线程,我把它变成一个无限循环。检查code用的的valgrind 的时候,我得到的内存泄漏。这里是我的code:

I create a thread and I put it into an infinite loop. I get memory leaks when checking the code with valgrind. Here is my code:

#include <pthread.h>
#include <time.h>

void thread_do(void){
    while(1){}
}

int main(){
    pthread_t th;   
    pthread_create(&th, NULL, (void *)thread_do, NULL);

    sleep(2);
    /* I want to kill thread here */
    sleep(2);
    return 0;
}

因此​​,一个线程在主创建,只是运行thread_do()所有的时间。有没有办法从内部的主要的2秒后杀呢?我曾经尝试都 pthread_detach(TH) pthread_cancel可以(TH)但是我还是泄漏。

So a thread is created in main and just runs thread_do() all the time. Is there a way to kill it from inside main after 2 seconds? I have tried both pthread_detach(th) and pthread_cancel(th) but I still get leaks.

推荐答案

由于@sarnold指出的,默认情况下你的线程不能与取消pthread_cancel可以()无调用是取消点的任何功能...但是这可以通过使用 pthread_setcanceltype()来设置线程的取消类型为异步,而不是推迟进行更改。要做到这一点,你会加入类似 pthread_setcanceltype(PT​​HREAD_CANCEL_ASYNCHRONOUS,NULL); 你的线程函数的开始不久,就开始循环之前。然后,你就可以通过调用来终止线程​​ pthread_cancel可以(TH)的main()

As @sarnold pointed out, by default your thread can't be cancelled with pthread_cancel() without calling any functions that are cancellation points... but this can be changed by using pthread_setcanceltype() to set the thread's cancellation type to asynchronous instead of deferred. To do that, you'd add something like pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL); near the start of your thread function, before you start the loop. You would then be able to terminate the thread by calling pthread_cancel(th) from main().

请注意,虽然,取消线程这种方式(无论是异步与否)不清理线程函数分配的资源(如由凯文在评论中说明)。为了干净地做到这一点,您可以:

Note, though, that cancelling threads this way (whether asynchronous or not) doesn't clean up any resources allocated in the thread function (as noted by Kevin in a comment). In order to do this cleanly, you can:


  • 确保线程不会做任何事情,它需要退出之前清理(例如,使用的malloc()来分配缓冲区)

  • 请确保您有线程清理后其他地方的一些方法,线程退出后

  • 使用 pthread_cleanup_push() pthread_cleanup_pop()添加清理处理程序来清理资源时该线程将被取消。注意,这仍然是有风险的,如果在取消的类型是同步的,因为线程可以分配资源并添加清理处理之间被取消。

  • 避免使用 pthread_cancel可以()并纷纷跟帖检查一些条件来决定何时终止(这将在长期运行的循环来检查)。因为你的线程会检查终止本身,它可以做任何清理就需要在检查后。

  • Ensure that the thread doesn't do anything it needs to clean up before exit (e.g. using malloc() to allocate a buffer)
  • Ensure that you have some way of cleaning up after the thread elsewhere, after the thread exits
  • Use pthread_cleanup_push() and pthread_cleanup_pop() to add cleanup handlers to clean up resources when the thread is cancelled. Note that this is still risky if the cancellation type is asynchronous, because the thread could be cancelled between allocating a resource and adding the cleanup handler.
  • Avoid using pthread_cancel() and have the thread check some condition to determine when to terminate (which would be checked in long-running loops). Since your thread then checks for termination itself, it can do whatever cleanup it needs to after the check.

实施的最后选择的一种方式是使用一个互斥作为标志,并与测试它pthread_mutex_trylock()包裹在循环测试中使用的函数:

One way of implementing the last option is to use a mutex as a flag, and test it with pthread_mutex_trylock() wrapped in a function to use in the loop tests:

#include <pthread.h>
#include <unistd.h>
#include <errno.h>

/* Returns 1 (true) if the mutex is unlocked, which is the
 * thread's signal to terminate. 
 */
int needQuit(pthread_mutex_t *mtx)
{
  switch(pthread_mutex_trylock(mtx)) {
    case 0: /* if we got the lock, unlock and return 1 (true) */
      pthread_mutex_unlock(mtx);
      return 1;
    case EBUSY: /* return 0 (false) if the mutex was locked */
      return 0;
  }
  return 1;
}

/* Thread function, containing a loop that's infinite except that it checks for
 * termination with needQuit() 
 */
void *thread_do(void *arg)
{
  pthread_mutex_t *mx = arg;
  while( !needQuit(mx) ) {}
  return NULL;
}

int main(int argc, char *argv[])
{
  pthread_t th;
  pthread_mutex_t mxq; /* mutex used as quit flag */

  /* init and lock the mutex before creating the thread.  As long as the
     mutex stays locked, the thread should keep running.  A pointer to the
     mutex is passed as the argument to the thread function. */
  pthread_mutex_init(&mxq,NULL);
  pthread_mutex_lock(&mxq);
  pthread_create(&th,NULL,thread_do,&mxq);

  sleep(2);

  /* unlock mxq to tell the thread to terminate, then join the thread */
  pthread_mutex_unlock(&mxq); 
  pthread_join(th,NULL);

  sleep(2);
  return 0;
}

如果线程不沾边(它一般不是默认),你应该停止线程之后调用在pthread_join()。如果线程分离,你并不需要加入它,但你不会知道什么时候它终止(或甚至约,除非添加另一种方式来表明它的退出)。

If the thread is not detached (it generally isn't by default), you should call pthread_join() after stopping the thread. If the thread is detached, you don't need to join it, but you won't know exactly when it terminates (or even approximately, unless you add another way to indicate its exit).

这篇关于我怎么能杀的pthread是一个无限循环,从外循环?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆