线程不作用于全局变量

时间:2016-08-05 18:44:12

标签: c multithreading pthreads

我有一个庞大的多线程代码库。有100个主题。 99个线程具有与其中每个线程相关联的函数do_thread_operations。第100个线程有一个与之关联的操作monitor_99threads

do_thread_operations有无限循环,因此它们永远不会停止。 monitor_99threads跟踪时间。它启动一分钟后,必须关闭所有99个线程并返回主线程。

以下是我的代码。

#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>

int *to_close_thread;

void * do_thread_operations(void * thread_data){
    int i = *(int *)thread_data;
    while (1){
       //do something
       if (to_close_thread[i]) break;
    }
}

void * monitor_99threads(void * data){ 
    int i = 0;
    while(1){
       i++;
       if(i > 60){
          for (int i = 0; i < 99; ++i){
              printf("Closing %d", i);
              to_close_thread[i] = 1;  
          }
       }
    }
}

int main(){
    to_close_thread = (int *)malloc(99 * sizeof(int));
    memset(to_close_thread, 0, 99*sizeof(int));
    pthread_t threads[100];
    for (int i = 0; i < 99; ++i){
        int j = i;
        pthread_create(&threads[i], NULL, do_thread_operations, (void *)&j);
    }
    pthread_create(&threads[99], NULL, monitor_99threads, NULL);
    for (int i = 0; i < 100; ++i){
        pthread_join(threads[i], NULL);
    }

}

问题是虽然关闭打印,但线程不会从它们的循环中断开。

2 个答案:

答案 0 :(得分:2)

除了@ P.P。描述的问题之外,_Atomic的指示对象似乎存在同步问题。由于元素不是do_thread_operations()并且在不保护互斥锁,信号量或其他同步对象的情况下访问它们,control_99threads()线程可能看不到to_close_thread执行的任何写入。

顺便提一下,请注意,将指针作为线程参数传递给 for (int i = 0; i < 99; ++i){ pthread_create(&threads[i], NULL, do_thread_operations, (void *) (to_close_thread + i)); } 基址的偏移量有点愚蠢,而只需将指针直接传递给相应的元素即可。那么你不需要任何辅助变量:

do_thread_operations

int *可以将其强制转换回mimemagic并直接取消引用(在互斥锁或其他适当的同步对象的保护下)。

答案 1 :(得分:1)

下面,

  for (int i = 0; i < 99; ++i){
        int j = i;
        pthread_create(&threads[i], NULL, do_thread_operations, (void *)&j);
    }

您正在传递j的地址,该地址具有块范围且具有自动存储持续时间。你应该这样:

    int arr[100] = {0}; /* adjust the number or allocate using malloc as per needs */
    for (int i = 0; i < 99; ++i){
        arr[i] = i;
        pthread_create(&threads[i], NULL, do_thread_operations, &arr[i]);
    }

另一个问题是你的监听线程在发送结束消息后没有中断。实际上,它在无限循环中运行。当满足(无论)条件时,您可能需要break;语句。