首页 > 解决方案 > 如何从线程返回后立即获得返回值,具有多个线程C?

问题描述

第一次问一个问题希望它会很有成效:) 我有 10 个线程正在运行,我需要 main 打印 2 件事:

  1. 从线程返回的值。
  2. 当所有线程完成后,以与发送到线程相同的顺序打印所有值的向量。

现在,程序从函数打印“--->”,这意味着它完成了胎面,但我需要它从 main 打印它们。

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>

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

//sem_t mutex;

void *myThread(void *args)
{
   int argptr=do123(*(int*)args);
   printf("--->%d\n",argptr);
 //  sem_wait(&mutex);
   //*(int*)args=do123((int)args);

   return (void*)argptr;
}

int main()
{

    int nums[10]={17,65,34,91,92,93,33,16,22,75};
    int TemPnums[10]={17,65,34,91,92,93,33,16,22,75};
    int res[10]={0};
    //pthread_t t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
    pthread_t theads[10];

    for (int i = 0;  i < 10; i++) {
        res[i]=nums[i];
        pthread_create(&theads[i], NULL, myThread, &TemPnums[i]);
    }
    // pthread_join(&theads[10], &status);
    for (int i = 0;  i < 10; i++) {
         void *status;
         pthread_join(theads[i], &status);
        res[i]=(int)status;
    }
    for (int i = 0;  i < 10; i++) {
     printf("%d\n",res[i]);
    }


}

int do123(int num)
{
    int k=0;
    while(num!=1){
        if(num%2==1){
            num=num*3+1;
            k++;
        }else{
            num=num/2;
            k++;
        }
    }
    return k;
}

输出:

--->12
--->92
--->27
--->13
--->17
--->17
--->26
--->14
--->4
--->15
12
27
13
92
17
17
26
4
15
14

标签: cmultithreadingpthreadsreturn-value

解决方案


C 中的线程加入的时间不受同一线程执行时间的影响,也不受其顺序决定。这意味着在我的系统上,线程执行和加入 10 个线程池的顺序可能因您的系统而异。例如,使用此修改后的代码版本(请参阅帖子底部的更改说明):

#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>

#include <cstdint>
//sem_t mutex;

int do123(int); // Added (1)

void *myThread(void *args)
{
    size_t argptr = do123(*(int *)args);
    printf("--->%d\n", argptr);
    //  sem_wait(&mutex);
    //*(int*)args=do123((int)args);

    return (void *)argptr;
}

int main()
{
    int nums[10]     = {17, 65, 34, 91, 92, 93, 33, 16, 22, 75};
    int TemPnums[10] = {17, 65, 34, 91, 92, 93, 33, 16, 22, 75};
    int res[10]      = {0};
    //pthread_t t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
    pthread_t theads[10];

    for (int i = 0; i < 10; i++)
    {
        res[i] = nums[i];
        pthread_create(&theads[i], NULL, myThread, &TemPnums[i]);
    }
    // pthread_join(&theads[10], &status);
    for (int i = 0; i < 10; i++)
    {
        void *status;
        pthread_join(theads[i], &status);
        res[i] = (size_t)status;
    }
    for (int i = 0; i < 10; i++)
    {
        printf("%d\n", res[i]);
    }
}

int do123(int num)
{
    int k = 0;
    while (num != 1)
    {
        if (num % 2 == 1)
        {
            num = num * 3 + 1;
            k++;
        }
        else
        {
            num = num / 2;
            k++;
        }
    }
    return k;

我得到输出:

--->12
--->27
--->13
--->92
--->17
--->17
--->26
--->4
--->15
--->14
12
27
13
92
17
17
26
4
15
14

如果您的目标是确保线程以与在辅助函数中为其分配值的顺序相同的顺序加入到主函数中的数组中,我建议实现一种方法来在一个线程分配了其值后阻塞后续线程给它。为此,您可以使用信号量或互斥体来实现系统。

关于信号量的文档:https ://www.tutorialspoint.com/how-to-use-posix-semaphores-in-c-language

关于互斥锁的文档:https ://www.tutorialspoint.com/deadlock-with-mutex-locks

简而言之,流程应该是当一个线程进入do123()时,锁定所有其他线程不进入该函数。让该线程上的所有工作都完成,并让它从函数返回并分配给它在数组中的相应索引。在此之后,您应该解锁下一个线程并重复。

我建议阅读这些内容以更好地了解线程的工作原理。祝你好运。

变更说明:

(1) 在代码中使用函数之前,您必须添加函数声明。您在下面调用它时定义了函数。编译器不知道此函数,因为它从“自上而下”查看您的代码。

由于大小取决于您的操作系统(16 位、32 位等),因此您会通过将类型 void* 转换为 int 来失去精度。我将它们更改为 size_t 结构,这将确保非负值并考虑精度损失。


推荐阅读