【问题标题】:how to use threads and array in C如何在 C 中使用线程和数组
【发布时间】:2011-03-16 11:09:07
【问题描述】:

问题是: 用大小为M的全局整数一维数组A编写程序。使用线程,主线程用随机整数初始化A和M,创建N个线程,使得第i个线程找到Ai = M * Ai,最后打印数组 A。

我的问题是数组初始化出错,我也不确定是否以正确的方式创建线程。 我希望我清楚地解释了我的问题。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int M;
int [10] A;

void *run(void *t)
{
   A[(int)t]=A[(int)t]*M;
   pthread_exit(NULL);
}


int main()
{
   pthread_t [10] th;
   srand(time(0))%20;
   M=rand();
   int t;
   for(t = 0; t < 10; t++)
   {
     pthread_create(&th[t], NULL, run, (void *)t);
   }

   int j;
   for(j=0;j<10;j++)
    A[j]=j;

   int i;
   for(i = 0; i < 10; i++)
   {
     pthread_join(th[i], NULL);
     printf("%d:  %d\n", i,A[i]);
   }

   printf("Thread main\n");
   pthread_exit(NULL);
}

这些是错误:

que1.c:5: error: expected identifier or ‘(’ before ‘[’ token
que1.c: In function ‘run’:
que1.c:9: error: ‘A’ undeclared (first use in this function)
que1.c:9: error: (Each undeclared identifier is reported only once
que1.c:9: error: for each function it appears in.)
que1.c: In function ‘main’:
que1.c:16: error: expected identifier or ‘(’ before ‘[’ token
que1.c:17: error: void value not ignored as it ought to be
que1.c:22: error: ‘th’ undeclared (first use in this function)
que1.c:27: error: ‘A’ undeclared (first use in this function)

【问题讨论】:

  • 你能更正你上面的代码吗?

标签: c multithreading arrays global-variables


【解决方案1】:

您似乎拥有 Java 背景(或 D),正如您所写的 int [10] A。您可以将其理解为 A 是 10 个整数的数组的变量 类型对象。但是在 C 语言中,这些事情有点不同。在 C 语言中,只有单独的原始变量,它们可以排列成一组连续的内存,这就是所谓的数组。这就是选择语法int A[10]; 的原因,这意味着:A 是一个指向整数的指针,指向自动分配的10 个整数的存储的开头

您的程序的下一个问题,尽管编译器不会报告它正在通过void* 类型传递一个整数。在 C 中,每个指针都可以转换为某个整数,但并非所有整数值都成为指针。 C 中的指针是抽象的东西:大多数实现选择使用内存地址作为它们的整数表示。但是通过单射 LUT 映射它们同样有效。因此,某些整数值可能无法映射到指针,因此无法正确传输。你真的应该传递一个真正的指针。

您对线程的使用也不是最理想的。在您的情况下,您正在疯狂地破坏缓存行,并且切换开销会消耗掉任何并行化增益。根据经验,您应该创建不超过 'number of CPU cores' + 2 个线程。考虑到所有这些,您可以执行以下操作:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

/* some prime number, so show what happens with uneven work sizes */
#define ELEMENTS 17

int M;
int A[ELEMENTS];

struct WorkletInfo {
   int *data_base;
   int count;
};

void *worklet(void *t)
{
   int i;
   struct WorkletInfo *wi = t; /* note: no cast here */
   if(!wi)
       return 0;

   for(i=0; i < wi->count; i++)
       wi->data_base[i] *= M;

   return wi;
}

#define N_CPUS 4
#define NUM_THREADS (N_CPUS+1)

int main(int argc, char *argv[])
{
   int t, ec;
   pthread_t th[NUM_THREADS];
   int remaining_elements;
   int const elements_per_worklet = ELEMENTS/NUM_THREADS;

   srand(time(0));
   M=rand();

   /* you must initialize the data a thread will access before starting the thread */
   for(t = 0; t < ELEMENTS; t++)
       A[t]=t+1; /* 0 * x = 0, so give it some nonzero value */

   remaining_elements = ELEMENTS - (elements_per_worklet*NUM_THREADS);
   ec = 0;
   for(t = 0; t < NUM_THREADS; t++)
   {
       struct WorkletInfo *wi = malloc(sizeof(*wi));
       wi->data_base = &A[ec];

       wi->count = elements_per_worklet;
       if(t<remaining_elements) {
           wi->count++;
       }
       ec += wi->count;

       pthread_create(&th[t], NULL, worklet, wi);
   }

   ec = 0;
   for(t = 0; t < NUM_THREADS; t++)
   {
       int i;
       struct WorkletInfo *wi;
       void *retval;
       pthread_join(th[t], &retval);

       if(!retval)
           continue;

       wi = retval;

       for(i = 0; i < wi->count; i++, ec++)
           printf("worklet %d, worklet element %d => total element %d:  %d\n", 
              t, i, ec, 
          wi->data_base[i]);

       free(wi);
       }

   printf("Thread main\n");

   return 0;
}

这个程序的输出是这样的:

worklet 0, worklet element 0 => total element 0:  300787748
worklet 0, worklet element 1 => total element 1:  601575496
worklet 0, worklet element 2 => total element 2:  902363244
worklet 1, worklet element 0 => total element 3:  1203150992
worklet 1, worklet element 1 => total element 4:  1503938740
worklet 1, worklet element 2 => total element 5:  1804726488
worklet 1, worklet element 3 => total element 6:  2105514236
worklet 2, worklet element 0 => total element 7:  -1888665312
worklet 2, worklet element 1 => total element 8:  -1587877564
worklet 2, worklet element 2 => total element 9:  -1287089816
worklet 3, worklet element 0 => total element 10:  -986302068
worklet 3, worklet element 1 => total element 11:  -685514320
worklet 3, worklet element 2 => total element 12:  -384726572
worklet 3, worklet element 3 => total element 13:  -83938824
worklet 4, worklet element 0 => total element 14:  216848924
worklet 4, worklet element 1 => total element 15:  517636672
worklet 4, worklet element 2 => total element 16:  818424420
Thread main exit

【讨论】:

    【解决方案2】:

    您的第一个问题纯粹是语法问题。这是无效的 C:

    int [10] A;
    

    应该是:

    int A[10];
    

    pthread_t [10] th; 也是如此。

    【讨论】:

    • 你是对的,这是完全正确的。我更正了我的代码,但第 17 行仍然有一个错误。
    • 错误说:que1.c:17:错误:无效值没有被忽略,因为它应该被忽略
    • @Tomy:错误信息告诉你错误信息在哪里!如果第一条错误消息涉及第 17 行,那么请查看第 17 行并找出其中的问题所在。无意冒犯,但如果您不知道如何解释错误消息并解决您的语法问题,那么您可能不应该尝试编写多线程 C 程序......
    【解决方案3】:

    除了@Oli Charlesworth的回答,srand不返回任何值,它被声明为void,所以你不能写srand(time(0)) % 20

    【讨论】:

      猜你喜欢
      • 2020-10-09
      • 2020-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-14
      • 2012-05-26
      相关资源
      最近更新 更多