如何通过线程将数组作为返回值传递?

时间:2018-04-01 23:44:05

标签: c linux multithreading unix pthreads

我正在开发一个创建线程的函数,并根据某个用户输入的值计算Fibonacci序列。例如,如果用户输入5,则输出将为:0 1 1 2 3 5

但是,必须在创建的线程中计算序列,并且必须在退出线程后打印出结果。

我可以创建线程并计算序列,但我需要使用fibSequence[]pthread_exit将数组pthread_join传回原始线程。我无法搞清楚语法,也找不到任何传递数组的例子。

到目前为止我所拥有的: 我创建了一个由新创建的线程调用的函数fib_runner()。创建Fibonacci序列并将其放入数组fibSequence[]。我需要将其传递回main函数。我暂时打印出函数中的序列,但它应该打印在主函数中。

谢谢!

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

void* fib_runner(void* arg)
{
    int *limit_ptr = (int*) arg;
    int limit = *limit_ptr;
    int fibSequence[limit];

    int size = sizeof(fibSequence)/sizeof(fibSequence[0]);
    printf("Size: %d\n", size);

    fibSequence[0] = 0;
    fibSequence[1] = 1;

    for (int i = 2; i <= size; i++)
    {
        fibSequence[i] = fibSequence[i-1] + fibSequence[i-2];
    }

    for (int i = 0; i <= size; i++)
    {
        printf("%d ", fibSequence[i]);
    }
    pthread_exit(0);
}

int main(int argc, char **argv)
{
    int limit;
    printf("Enter Number: ");
    scanf("%d", &limit);

    pthread_t tid;
    pthread_attr_t attr;
    pthread_attr_init(&attr);

    pthread_create(&tid, &attr, fib_runner, &limit);
    pthread_join(tid, NULL);
}

3 个答案:

答案 0 :(得分:0)

目前,数组是一个局部变量,因此当函数退出时它将超出范围。您需要为它动态分配内存:

int *fibSequence = malloc(sizeof(int) * limit);

然后从函数返回此指针:

return fibSequence;

main函数中,然后传递指针的地址以接收此值。然后,您可以打印阵列的内容。完成后,请务必free

int *fibSequence;
pthread_join(tid, (void **)&fibSequence);

for (int i = 0; i < limit; i++)
{
    printf("%d ", fibSequence[i]);
}
free(fibSequence);

此外,您在线程功能中不需要size,因为它与limit相同,并且您当前计算它的方式无论如何都不会工作现在有一个指针而不是一个数组。 fib_runner中的循环限制也超过了数组的结尾。退出条件应为i < size,而不是i <= size

答案 1 :(得分:0)

进程内运行的所有线程共享相同的地址空间,文件描述符,堆栈和其他与进程相关的属性。

线程按定义共享内存,它们除了堆栈和局部变量之外没有任何东西;

如果你使fibSequence[limit]全局,则所有线程都可以访问它。

您还可以在fibSequence[limit]中的堆栈上声明main并将指针传递给您的主题。

要传递多个参数,将它们包装在结构中会很方便。 以下解决方案采用:

struct arg_struct {
    int limit;
    int *ptrFib;
}args;

程序:

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

struct arg_struct {
    int limit;
    int *ptrFib;
}args;

void* fib_runner(void* arg)
{
    struct arg_struct *a = (struct arg_struct *) arg;
    int size = a->limit;
    int * fibSequence = a->ptrFib;  

    fibSequence[0] = 0;
    fibSequence[1] = 1;

    for (int i = 2; i <= size; i++){
        fibSequence[i] = fibSequence[i-1] + fibSequence[i-2];
    }    
    pthread_exit(0);
}

int main(int argc, char **argv)
{
    int limit;
    printf("Enter Number: ");
    scanf("%d", &limit);
    int fibSequence[limit];

    struct arg_struct argF;
    argF.limit = limit;
    argF.ptrFib = fibSequence;

    pthread_t tid;
    pthread_attr_t attr;
    pthread_attr_init(&attr);

    pthread_create(&tid, &attr, fib_runner, &argF);
    pthread_join(tid, NULL);

    for (int i = 0; i <= limit; i++){
        printf("%d ", fibSequence[i]);
    }
}

输出:

Enter Number: 5                                                                                                                                                                                                                                                               
0 1 1 2 3 5 

具有全局变量argF的解决方案当然是可行的,但不太优雅。

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

struct arg_struct {
    int limit;
    int *ptrFib;
}args;

struct arg_struct argF;

void* fib_runner()
{
    int size = argF.limit;
    int * fibSequence = argF.ptrFib;

    fibSequence[0] = 0;
    fibSequence[1] = 1;

    for (int i = 2; i <= size; i++){
        fibSequence[i] = fibSequence[i-1] + fibSequence[i-2];
    }
    pthread_exit(0);
}

int main(int argc, char **argv)
{
    int limit;
    printf("Enter Number: ");
    scanf("%d", &limit);
    int fibSequence[limit];

    argF.limit = limit;
    argF.ptrFib = fibSequence;

    pthread_t tid;
    pthread_attr_t attr;
    pthread_attr_init(&attr);

    pthread_create(&tid, &attr, fib_runner, NULL);
    pthread_join(tid, NULL);

    for (int i = 0; i <= limit; i++){
        printf("%d ", fibSequence[i]);
    }
}

答案 2 :(得分:0)

您必须将值void *传递给pthread_exit pthread_exit(( void * ) &fibSequence,一旦调用该函数,传入的值将填充第二个参数pthread_join ,第二个参数将是指针void **的指针,它将保存传递给pthred_exit的值