代码之家  ›  专栏  ›  技术社区  ›  wishi

Linux-强制单核执行和使用pthread调试多线程

  •  2
  • wishi  · 技术社区  · 14 年前

    我正在用C、pthread和Linux调试多线程问题。在我的MacOS 10.5.8上,c2d运行良好,在我的Linux计算机上(2-4核),它产生不需要的输出。

    我没有经验,所以我附上了我的代码。这相当简单:每个新线程都会再创建两个线程,直到达到最大值。所以没什么大不了的…就像我几天前想的那样。

    valgrind --tool=drd --read-var-info=yes --trace-mutex=no ./threads
    

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    #define MAX_THR      12
    #define NEW_THR      2
    
    int wait_time = 0;  // log global wait time
    int num_threads = 0;    // how many threads there are
    pthread_t threads[MAX_THR]; // global array to collect threads
    pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; // sync
    
    struct thread_data 
    {
        int nr;             // nr of thread, serves as id
        int time;           // wait time from rand()
    };
    struct thread_data thread_data_array[MAX_THR+1];
    
    
    void 
    *PrintHello(void *threadarg)
    {
    
      if(num_threads < MAX_THR){
        // using the argument
    
        pthread_mutex_lock(&mut);
        struct thread_data *my_data;
        my_data = (struct thread_data *) threadarg;
    
        // updates
        my_data->nr = num_threads;
        my_data->time= rand() % 10 + 1;
    
        printf("Hello World! It's me, thread #%d and sleep time is %d!\n", 
                    my_data->nr, 
                    my_data->time); 
    
         pthread_mutex_unlock(&mut);
    
       // counter
       long t = 0;
    
       for(t = 0; t < NEW_THR; t++){
            pthread_mutex_lock(&mut);
                num_threads++;
                wait_time += my_data->time;
               pthread_mutex_unlock(&mut);
            pthread_create(&threads[num_threads], NULL, PrintHello, &thread_data_array[num_threads]);
          sleep(1);
       }
        printf("Bye from %d thread\n", my_data->nr);
    
       pthread_exit(NULL);
       }
       return 0;
    }
    
    int 
    main (int argc, char *argv[])
    {
    
        long t = 0;
        // srand(time(NULL));
        if(num_threads < MAX_THR){
           for(t = 0; t < NEW_THR; t++){
              // -> 2 threads entry point
              pthread_mutex_lock(&mut);
                     // rand time
                     thread_data_array[num_threads].time  = rand() % 10 + 1;
               // update global wait time variable
                  wait_time += thread_data_array[num_threads].time;
                  num_threads++;
            pthread_mutex_unlock(&mut);
            pthread_create(&threads[num_threads], NULL, PrintHello, &thread_data_array[num_threads]);
             pthread_mutex_lock(&mut);
            printf("In main: creating initial thread #%ld\n", t);
            pthread_mutex_unlock(&mut);
    
          }
        }
    
       for(t = 0; t < MAX_THR; t++){
            pthread_join(threads[t], NULL);
        }
    
        printf("Bye from program, wait was %d\n", wait_time);
        pthread_exit(NULL);
    }
    

    printf("Bye from %d thread\n", my_data->nr);
    

    In main: creating initial thread #0
    Hello World! It's me, thread #2 and sleep time is 8!
    In main: creating initial thread #1
    [...]
    Hello World! It's me, thread #11 and sleep time is 8!
    Bye from 9 thread
    Bye from 5 thread
    Bye from -1376900240 thread
    [...] 
    

    3 回复  |  直到 14 年前
        1
  •  3
  •   nategoose    14 年前

    const

    volatile

    pthread_mutex_t

    x = x + 1;
    

    x

    lock

     int local_thread_count;
     int create_a_thread;
    
     pthread_mutex_lock(&count_lock);
     local_thread_count = num_threads;
     if (local_thread_count < MAX_THR) {
         num_threads = local_thread_count + 1;
         pthread_mutex_unlock(&count_lock);
    
         thread_data_array[local_thread_count].nr = local_thread_count;
                                               /* moved this into the creator
                                                * since getting it in the
                                                * child will likely get the
                                                * wrong value. */
    
         pthread_create(&threads[local_thread_count], NULL, PrintHello,
                                           &thread_data_array[local_thread_count]);
    
     } else {
         pthread_mutex_unlock(&count_lock);
     }
    

    num_threads local_thread_count NEW_THR 纽瑟斯 是2和 MAX_THR - num_threads 是1(不知何故),那么你必须以某种方式正确地处理它。

    现在,所有这些都说,可能还有另一种方法可以通过使用信号量来完成类似的事情。信号量类似于互斥体,但它们有一个与之相关联的计数。您不会得到一个值作为线程数组的索引(读取信号量计数的函数并不能真正给出这个值),但我认为应该提到它,因为它非常相似。

    man 3 semaphore.h
    

    会告诉你一点。

        2
  •  1
  •   lijie    14 年前

    num_threads 至少应该有标记 volatile 最好也标记为原子(尽管我相信 int 实际上很好),这样至少不同线程看到相同值的可能性更高。您可能希望查看汇编程序输出,以查看何时写入 num_thread 对记忆的记忆实际上是假定发生的。

        3
  •  0
  •   bencef    14 年前

    https://computing.llnl.gov/tutorials/pthreads/#PassingArguments

    这似乎就是问题所在。您需要对线程的数据结构进行malloc。