Linux,C:几秒后终止多线程(计时器?)

时间:2022-01-31 01:24:12

Linux, C. I created multiple threads to run workloads, and I want to signal those threads to stop/terminate after a specified seconds/time out. How do I implement this by C?

Linux,C。我创建了多个线程来运行工作负载,我希望在指定的秒/超时后发出停止/终止这些线程的信号。我如何用C实现这个?

void *do_function(void *ptr)
{
    //calculating, dothe workload here;
}

int run(struct calculate_node *node)
{
    pthread_t threads[MAX_NUM_THREADS];
    for (t = 0; t < node->max_threads; t++) {
        rc = pthread_create(&threads[t], NULL, do_function, (void*)node);
        if(rc) return -1;
    }

    //how do I create timer here to fire to signal those threads to exit after specified seconds?


    for (t = 0; t < node->max_threads; t++) {
        pthread_join(threads[t], NULL);
    }
    free(threads);
}

thanks!

2 个解决方案

#1


5  

Not sure if there's a portable way to create a timer event, but if main doesn't have anything else to do, it could simply call sleep to waste time.

不确定是否有一种可移植的方式来创建一个计时器事件,但如果main没有其他任何事情要做,它可能只是简单地调用sleep来浪费时间。

As for signaling the threads, you have two choices: cooperative termination or non-cooperative termination. With cooperative termination, the thread must periodically check a flag to see if it's supposed to terminate. With non-cooperative termination, you call pthread_cancel to end the thread. (See the man page for pthread_cancel for information about additional functions that can be used to gracefully end the thread.)

至于信令线程,您有两种选择:协作终止或非协作终止。通过协作终止,线程必须定期检查标志以查看它是否应该终止。使用非协作终止,您可以调用pthread_cancel来结束线程。 (有关可以用于正常结束线程的其他函数的信息,请参阅pthread_cancel的手册页。)

I find cooperative termination easier to implement. Here's an example:

我发现合作终止更容易实现。这是一个例子:

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

static int QuitFlag = 0;
static pthread_mutex_t QuitMutex = PTHREAD_MUTEX_INITIALIZER;

void setQuitFlag( void )
{
    pthread_mutex_lock( &QuitMutex );
    QuitFlag = 1;
    pthread_mutex_unlock( &QuitMutex );
}

int shouldQuit( void )
{
    int temp;

    pthread_mutex_lock( &QuitMutex );
    temp = QuitFlag;
    pthread_mutex_unlock( &QuitMutex );

    return temp;
}

void *somefunc( void *arg )
{
    while ( !shouldQuit() )
    {
        fprintf( stderr, "still running...\n");
        sleep( 2 );
    }

    fprintf( stderr, "quitting now...\n" );
    return( NULL );
}

int main( void )
{
    pthread_t threadID;

    if ( pthread_create( &threadID, NULL, somefunc, NULL) != 0 )
    {
        perror( "create" );
        return 1;
    }

    sleep( 5 );
    setQuitFlag();
    pthread_join( threadID, NULL );
    fprintf( stderr, "end of main\n" );
}

#2


2  

First, you need to create and start the time. In the example below the timer will invoke a "stop" function, that will be responsible for interrupting your threads. In a way, it is one of the simplest options.

首先,您需要创建并开始时间。在下面的示例中,计时器将调用“stop”函数,该函数将负责中断您的线程。在某种程度上,它是最简单的选择之一。

void *notify_stop(void *); // Prototype

int run(struct calculate_node *node)
{
  ...

  struct sigevent sev;
  timer_t timer;
  struct itimerspec tspec = { 0 };
  sev.sigev_notify = SIGEV_THREAD;  // type of timer event
  sev.sigev_notify_function = notify_stop; // call function
  timer_create(CLOCK_MONOTONIC, &sevent, &timer);
  tspec.it_interval.tv_sec = 5; // set time interval
  tspec.it_interval.tv_nsec = 0;
  tspec.it_value.tv_sec = 0;
  tspec.it_value.tv_nsec = 0;
  timer_set(timer, &tspec, NULL); // start timer

  ....
}

Now, you need to decide how you want to stop your threads. One way is to use some shared variable to indicate the exit condition:

现在,您需要决定如何停止线程。一种方法是使用一些共享变量来指示退出条件:

volatile bool do_stop = false;
void *do_function(void *ptr)
{
  while (!do_stop)
  {
     //calculating, dothe workload here;
  }
}
void *notify_stop(void *)
{
  do_stop = true; // just set the variable to let other threads
                  // read it and stop
}

#1


5  

Not sure if there's a portable way to create a timer event, but if main doesn't have anything else to do, it could simply call sleep to waste time.

不确定是否有一种可移植的方式来创建一个计时器事件,但如果main没有其他任何事情要做,它可能只是简单地调用sleep来浪费时间。

As for signaling the threads, you have two choices: cooperative termination or non-cooperative termination. With cooperative termination, the thread must periodically check a flag to see if it's supposed to terminate. With non-cooperative termination, you call pthread_cancel to end the thread. (See the man page for pthread_cancel for information about additional functions that can be used to gracefully end the thread.)

至于信令线程,您有两种选择:协作终止或非协作终止。通过协作终止,线程必须定期检查标志以查看它是否应该终止。使用非协作终止,您可以调用pthread_cancel来结束线程。 (有关可以用于正常结束线程的其他函数的信息,请参阅pthread_cancel的手册页。)

I find cooperative termination easier to implement. Here's an example:

我发现合作终止更容易实现。这是一个例子:

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

static int QuitFlag = 0;
static pthread_mutex_t QuitMutex = PTHREAD_MUTEX_INITIALIZER;

void setQuitFlag( void )
{
    pthread_mutex_lock( &QuitMutex );
    QuitFlag = 1;
    pthread_mutex_unlock( &QuitMutex );
}

int shouldQuit( void )
{
    int temp;

    pthread_mutex_lock( &QuitMutex );
    temp = QuitFlag;
    pthread_mutex_unlock( &QuitMutex );

    return temp;
}

void *somefunc( void *arg )
{
    while ( !shouldQuit() )
    {
        fprintf( stderr, "still running...\n");
        sleep( 2 );
    }

    fprintf( stderr, "quitting now...\n" );
    return( NULL );
}

int main( void )
{
    pthread_t threadID;

    if ( pthread_create( &threadID, NULL, somefunc, NULL) != 0 )
    {
        perror( "create" );
        return 1;
    }

    sleep( 5 );
    setQuitFlag();
    pthread_join( threadID, NULL );
    fprintf( stderr, "end of main\n" );
}

#2


2  

First, you need to create and start the time. In the example below the timer will invoke a "stop" function, that will be responsible for interrupting your threads. In a way, it is one of the simplest options.

首先,您需要创建并开始时间。在下面的示例中,计时器将调用“stop”函数,该函数将负责中断您的线程。在某种程度上,它是最简单的选择之一。

void *notify_stop(void *); // Prototype

int run(struct calculate_node *node)
{
  ...

  struct sigevent sev;
  timer_t timer;
  struct itimerspec tspec = { 0 };
  sev.sigev_notify = SIGEV_THREAD;  // type of timer event
  sev.sigev_notify_function = notify_stop; // call function
  timer_create(CLOCK_MONOTONIC, &sevent, &timer);
  tspec.it_interval.tv_sec = 5; // set time interval
  tspec.it_interval.tv_nsec = 0;
  tspec.it_value.tv_sec = 0;
  tspec.it_value.tv_nsec = 0;
  timer_set(timer, &tspec, NULL); // start timer

  ....
}

Now, you need to decide how you want to stop your threads. One way is to use some shared variable to indicate the exit condition:

现在,您需要决定如何停止线程。一种方法是使用一些共享变量来指示退出条件:

volatile bool do_stop = false;
void *do_function(void *ptr)
{
  while (!do_stop)
  {
     //calculating, dothe workload here;
  }
}
void *notify_stop(void *)
{
  do_stop = true; // just set the variable to let other threads
                  // read it and stop
}