简体   繁体   中英

Close a thread based on a variable value from calling thread

I am using posix threads in C. I have two threads in my program, thread1 and thread2. thread1 starts thread2.

thread1 maintains a variable var1 based on which thread2 has to be exited safely.

thread2 calls many lengthy functions (whose runtime can be upto 5 sec). There are many memory allocations using malloc in thread2. As soon as var1 becomes true, I need to close thread2 but only after deallocating all allocated memories. How this can be done?

The code looks like this:

void * func1(void *arg)
{
   pthread_create(&thread2, &attr, func2, NULL);
   while(1)
   {
      // ...
      var1 = func3();
      if(var1 == true)
      {   
          // Cancel thread2
      }
      // ...
   }
}

void * func2(void *arg)
{
    // ...
    func4(); // runs for 2 sec
    char* var2 = malloc(10);
    func5(); // runs for 5 sec
    char* var3 = malloc(20);
    // ...
 cleanup:
    free(var2);
    free(var3);
    return (void*) 0;
}

There are several ways to accomplish that. Here's one:

From the perspective of thread1 you can simply use pthread_cancel on thread2 when the time comes. But you'd need to restructure thread2 accordingly to make sure it has cancellation points at safe places. You'd also need to restructure how you hold your data to allow a cancellation callback to be called for thread2:

struct func2_data {
  char *var2;
  char *var3;
};

void func2_cleanup(void *vdata) {
  struct func2_data *data = vdata;
  free(data->var2);
  free(data->var3);
}

void * func2(void *arg)
{
  struct func2_data data = {
    NULL, NULL
  };

  pthread_cleanup_push(func2_cleanup, &data);

  // ....    

  func4();
  data.var2 = malloc(10);
  pthread_testcancel();

  func5();
  data.var3 = malloc(10);
  pthread_testcancel();

  // ....        

  pthread_cleanup_pop(1);
  return NULL;
}

So what happens here?

  1. All the pointers that need freeing are bundles together and initialized to NULL. This allows a call to free to act upon them as no-op if the cleanup function is called prior to any single variable being assigned.

  2. A callback is registered to free the pointers. That callback will be called at any cancellation point. Including when the thread returns from its handler function. So you don't need to take care of it explicitly there, other than calling pop.

  3. Cancellation points are added with pthread_testcancel , at various "safe" places. Thus allowing the thread to end prematurely between calculations. Add them as you see fit.

Even though your question in not understandable properly, In below code I am giving an Idea to handle the things. Use ptread_join for safe exit of threads

void * func1(void *arg)
{
    pthread_create(&thread2, &attr, func2, (void*)&var1); /* Pass addr of var1 as argument to thread*/
    while(1)
    {
        ...
        var1 = func3();
        if(var1 == TRUE){
            int *ret;
            pthread_join(thread2,&ret);
        }
        ...
    }
}

void * func2(void *arg)
{
    bool *check = (bool*)arg;
    ...
    func4(); // runs for 2 sec
    if(*check == TRUE)
        goto end;
    char* var2 = malloc(10);
    func5(); // runs for 5 sec
    if(*check == TRUE)
        goto clean_var2;
    char* var3 = malloc(20);
    ...
    cleanup:
    free(var3);
    clean_var2:
    free(var2);
    end:
    return (void*) 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM