【问题标题】:C threads and joiningC 螺纹和连接
【发布时间】:2013-12-07 21:16:35
【问题描述】:

我有一个关于 C 线程及其返回值的问题。我的目标是找到开始数和结束数之间的所有质数。我将有 4 个线程,每个线程执行四分之一的范围。

例如,1 到 100 之间的素数。

  • 线程 1 找到 1 - 25 之间的素数
  • 线程 2 26 - 50
  • 线程 3 51 - 75
  • 线程 4 76 - 100

所有素数都将存储在一个数组中,并且会有一个计算素数的函数。

我的问题是,当我加入线程时

pthread_join(tids[i], ptr);

ptr 将是一个指向所有素数组合数组的指针,1 - 100?

如果我使用 for 循环打印值的含义

printf("%d", ptr[i]); 

它会将 1 - 100 的所有素数打印为一个大数组吗?

我加入了 4 个独立的数组吗?

谢谢

【问题讨论】:

    标签: c multithreading pthreads


    【解决方案1】:

    phtread_join() 将通过 ptr 返回相应线程传递给 pthread_exit() 的内容。每个线程都独立工作并计算自己的素数集,因此,每个线程都应该创建自己的数组,并且在所有线程加入后,您将打印每个数组的结果。为了能够返回素数的结果集及其计数,我们必须使用自己的结构类型:

    struct comp_result {
         unsigned *p_arr;
         unsigned count;
    };
    

    我将说明不加锁的方式:

    compute_thread (...) {
        ...
        struct comp_result *p_res = malloc(sizeof(struct comp_result));        
        p_res->p_arr = NULL;
        p_res->count = 0;
        for (num = start; num < end; num++) {
             if (is_prime(num)) { 
                  p_res->count++; /// increment number of primes and expand our storage
                  p_res->p_arr = realloc(p_res->p_arr, p_res->count*sizeof(int));
                  p_res->p_arr[p_res->count-1] = num; // save prime in result array
             }
        }  
    
        // pass pointer to per-thread result data
        pthread_exit(p_res);
    }
    
    
     main () {
          .... // create threads
          ....
          for (i = 0; i < num_of_threads; i++) {
               struct comp_result *p_res;
               // retrieve and print array from i-thread
               pthread_join(tids[i], &p_res);
               for (num = 0; num < p_res->count; num++) {
                    printf(" %d ", p_res->p_arr[num]);
               }
               free(p_res->p_arr);
               free(p_res);
          }
     } 
    

    带有锁定的插图需要多一种结构类型,因为我们会将指向结果共享数据的指针传递给每个线程:

    struct control {
        unsigned start;
        unsigned end;
        struct comp_result *p_res;
    }
    
    compute_thread (ptr) {
        struct control *p_cont = (struct control*)ptr;
        // retrieve the pointer to shared, but be accurate with it!
        struct comp_result *p_res = p_cont->p_res;
    
        // initialize lock
        pthread_mutex_init(&p_res->lock, NULL);
    
        ...
        for (num = p_cont->start; num < p_cont->end; num++) {
             if (is_prime(num)) {
                  pthread_mutex_lock(&p_control->lock);
                  // modify shared data with locking 
                  p_res->count++; /// increment number of primes and expand our storage
                  p_res->p_arr = realloc(p_res->p_arr, p_res->count*sizeof(int));
                  p_res->p_arr[p_res->count-1] = num; // save prime in result array
                  pthread_mutex_unlock(&p_control->lock);
             }
        }  
    
        pthread_exit(NULL);
    }
    
    
     main () {
          //create one shared data and initialize it:
          struct comp_result *p_res = malloc(sizeof(struct comp_result));        
    
          p_res->p_arr = NULL;
          p_res->count = 0;
    
          for (i = 0; i < num_of_threads; i++) {
                // create per-thread control data:
                struct control *p_control = malloc(sizeof(struct control));        
                p_control->start = 
                p_control->end =
                p_control->p_res = p_res;
                pthread_crate(&tids[i], NULL, compute_thread, p_control);
          }
          ....
          for (i = 0; i < num_of_threads; i+++) {
               pthread_join(tids[i], NULL);
          }
          // now all threads are completed and we are ready to read result:
          for (num = 0; num < p_res->count; num++) {
               printf(" %d ", p_res->p_arr[num]);
          }
     } 
    

    【讨论】:

    • 好的,谢谢。我也可以声明一个 void *ptr = NULL;然后在我的加入函数中执行 pthread_join(tids[i], &ptr);这行得通吗?
    • 所以在这种情况下,ptr 是一个指向数组的变量。那么我可以使用 for 循环,将指针转换为我的结构类型,然后打印数组中的素数?
    • 既然我将有 4 个数组,我可以使用 ptr 变量创建一个数组并返回它吗?
    • @user2817240 是的,您可以使用 void *ptr 并在您编写时传递它,然后进行转换,但从技术上讲,这是相同的。是的,如果您有 4 个线程 - 您有 4 个数组,您可以再创建一个连接数组并从 4 复制到这个连接数组中。还有其他选项可以一直使用一个连接数组,但这需要锁定,例如使用互斥锁。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-03
    • 2013-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-31
    • 1970-01-01
    相关资源
    最近更新 更多