簡體   English   中英

根據調用線程中的變量值關閉線程

[英]Close a thread based on a variable value from calling thread

我在C中使用posix線程。我的程序中有兩個線程,thread1和thread2。 線程1啟動線程2。

線程1維護一個變量var1,基於該變量必須安全退出線程2。

thread2調用了許多冗長的函數(其運行時間最多為5秒)。 在thread2中有許多使用malloc的內存分配。 一旦var1變為true,我需要關閉thread2,但僅在取消分配所有已分配的內存之后。 如何做到這一點?

代碼如下:

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;
}

有幾種方法可以做到這一點。 這是一個:

從線程1的角度來看,您可以在時間到時在線程2上簡單地使用pthread_cancel 但是您需要相應地重組thread2,以確保它在安全的地方具有取消點。 您還需要重新構造數據的存儲方式,以允許為線程2調用取消回調:

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;
}

那么這里發生了什么?

  1. 所有需要釋放的指針都捆綁在一起並初始化為NULL。 如果在分配任何單個變量之前調用了清除函數,則允許以free操作的方式對其進行操作。

  2. 注冊了一個回調以釋放指針。 該回調將在任何取消點被調用。 包括線程何時從其處理函數返回。 因此,除了調用pop之外,您無需在其中明確地處理它。

  3. 取消點通過pthread_testcancel添加到各個“安全”位置。 因此,允許線程在計算之間過早結束。 根據需要添加它們。

即使您的問題無法正確理解,在下面的代碼中,我還是給出了一個想法來處理這些問題。 使用ptread_join安全退出線程

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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM