【问题标题】:how to return an array from a pthread如何从pthread返回一个数组
【发布时间】:2019-03-03 16:19:14
【问题描述】:

我一直试图从一个线程中取回一个整数数组。我想我真的很接近了。我得到的错误是关于在此处取消引用 void 指针和无效使用 void 表达式

assn3.c:29:29: 错误:取消引用‘void *’指针 [-Werror]

printf(" %d", (int)answer[j]);
                         ^

assn3.c:29:18: 错误:无效表达式的使用

printf(" %d", (int)answer[j]);

我尝试将函数的返回类型更改为 int*,但它似乎不喜欢那样。我在这里错过了什么?

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

void *getFactors(void *param);

int main(int argc, char *argv[])
{
    for(int i = argc; i > 0; i--)
    {
            void *answer;
            pthread_t tid;
            pthread_attr_t attr;
            if (atoi(argv[i])<0)
            {
                    fprintf(stderr, "%d must be > 0\n", atoi(argv[i]));
                    return -1;
            }

            pthread_attr_init(&attr);
            pthread_create(&tid, &attr, getFactors, argv[i]);
            pthread_join(tid, &answer);

            printf("%d", atoi(argv[i]));
            printf(":");

            for(int j = 0; j < sizeof(answer); j++)
            {
                    printf(" %d", (int)answer[j]);
            }
            printf("\n");
    }
}

还有线程函数

void *getFactors(void *param)
{
    int a[10];
    int n = atoi(param);

    int i = 0;
    while (n%2 == 0)
    {
            a[i] = 2;
            n/=2;
            i++;
    }
    int f=3;
    while (f * f <= n)
    {
            if (n % f == 0)
            {
                    a[i]=f;
                    n /= f;
                    i++;
            }
            else
            {
                    f += 2;
            }
    }
    if (n<1)
    {
            a[i]=n;
            i++;
    }

    int* buffer = (int*) malloc(i);
    buffer = a;
    return (void *) buffer;

    pthread_exit(0);
}

【问题讨论】:

    标签: c pthreads


    【解决方案1】:
    void *answer;
    ...
    int * answer_beeing_an_int_arr = answer;
    printf(" %d", answer_beeing_an_int_arr[j]);
    

    这就是你想要的。但你会发现:

    printf(" %d", (int)answer[j]); 
    

    不起作用。你为什么问?这是因为强制转换(int) 的优先级低于数组下标[j],而且您没有告诉编译器answer 是指向ints 的指针,只是它应该首先获取值,然后强制转换为 int。你想要这个:

    printf(" %d", ((int*)answer)[j]); 
    

    您想告诉编译器,答案是指向 int 的指针。然后你想添加那个指针 sizeof(int) * j 字节并取消引用它。

    记得free(answer)

    现在到你的代码:

    buffer = a;
    

    错了。它将指针分配给另一个指针。您想复制指针后面的值,而不是指针本身。你需要:

    memcpy(buffer, a, sizeof(int) * i);
    

    for (size_t j = 0; j < i; ++j) {
        buffer[j] = a[j];
    }
    

    复制数组值。

    ... = malloc(i);
    

    这将分配i 字节。 int 没有 1 个字节(CHAR_BIT 位,可能是 8 个)。它有更多。可以是 2 个,也可以是更多。 sizeof(int) 会告诉你int 有多少字节。所以它必须是:

    int *buffer = malloc(i * sizeof(int));
    

    或者我喜欢它:

    int *buffer = malloc(i * sizeof(*buffer));
    

    还有:

    int* buffer = (int*) malloc(i);
    ...
    return (void *) buffer;
    

    无需将指针投射到void*void*void* 是一个通用指针,它是一个空指针。只是:

    int* buffer = malloc(i * sizeof(*buffer));
    ...
    return buffer;
    

    【讨论】:

    • 好回答你比我快)),您还可以在线程中返回后添加关于无法访问的代码,并在没有参数的 for 循环中添加 sigfault,因为即使没有 args,argc 也会为 1我们尝试访问 NULL argv[1],在 for 循环中解决它 int i = argc - 1。
    • 对不起,我一直在忙其他事情。除了一件事之外,所有这些解决方案都非常有效。我发现 sizeof(buffer) 总是返回 8,而 sizeof(buffer) 总是返回 4,无论你在指针数组中放入了多少元素。那是因为当您在指针数组上使用 sizeof() 时,它只返回指针的大小,在我的例子中是 8。为了在我的主函数中正确打印结果,我在数组末尾添加了一个 0,然后将我的 for 条件更改为 ((int)answer)[j] != 0;
    【解决方案2】:

    这里有几个问题:

    1. for(int j = 0; j &lt; sizeof(answer); j++) // 这将不会告诉你数组中的#/元素

    2. pthread_join() 可能不是传回整数缓冲区的最佳方式

    3. 当然,printf(" %d", (int)answer[j]); 是一个编译错误:(

    建议:

    通读本教程,并相应地重构您的代码:

    http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html

    或者你可以浏览一下:

    http://www.cs.kent.edu/~ruttan/sysprog/lectures/multi-thread/multi-thread.html

    【讨论】:

      【解决方案3】:

      如前所述,您需要纠正一些问题。

      如前所述,不要使用局部变量作为返回地址。线程返回时将无法访问它。最好使用全局变量并动态分配内存。您可以在创建线程的函数中释放它。

      要访问由线程更改的变量,您可以使用 pthread_create(3) 中的第四个参数将其传递给线程函数,然后再访问它。或者使用 pthread_join 作为返回值来访问它。

      如果多个线程正在访问该变量,可能需要使用互斥锁或其他同步原语。

      下面给出了一个使用 pthread_join(3) 返回数组的简单示例。

          #include <stdio.h>
          #include <stdlib.h>
          #include <pthread.h>
          #include <errno.h>
      
          #define ARRAY_LEN 10
          void *functionPthread(void *);
      
          int *retArray;
      
          int main()
          {
                  int rc, i;
                  pthread_t th;
                  retArray = (int*) malloc(sizeof(int) *ARRAY_LEN);
      
                  if(rc = pthread_create(&th, NULL, &functionPthread, NULL))
                  {
                          printf("Thread creation failed, return code %d, errno %d", rc, errno);
                  }
      
                  pthread_join(th, (void**)&retArray);
      
                  for(i = 0; i < ARRAY_LEN; i++)
                          printf("%d ", retArray[i]);
                  printf("\n");
                  free(retArray);
                  return 0;
          }
      
          void *functionPthread(void *)
          {
                  int i;
                  for(i = 0; i < ARRAY_LEN; i++)
                          retArray[i] = i;
                  return retArray;
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-16
        • 2020-04-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-03
        • 2023-03-06
        • 2012-11-29
        • 2016-07-04
        相关资源
        最近更新 更多