linux多线程参数的传递

以下内容全部来自于b站码农论坛的个人空间_哔哩哔哩_bilibili

这位大哥是一位顶级大佬,有兴趣学c++的都可以去看一下他的视频。并且他还开源了他自己的框架,非常好用。 

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

// 与客户端通信的主函数
void *mainfunc1(void *arg);
void *mainfunc2(void *arg);
void *mainfunc3(void *arg);
void *mainfunc4(void *arg);
void *mainfunc5(void *arg);
int var = 1;
int main()
{
    pthread_t pthid1, pthid2, pthid3, pthid4, pthid5;

    // 创建一个线程
    if (pthread_create(&pthid1, NULL, mainfunc1, NULL)!= 0)
    {
        printf("线程创建失败,程序退出。\n");
        return -1;
    }
    var++;
    if (pthread_create(&pthid2, NULL, mainfunc2, NULL)!= 0)
    {
        printf("线程创建失败,程序退出。\n");
        return -1;
    }
    var++;
    if (pthread_create(&pthid3, NULL, mainfunc3, NULL)!= 0)
    {
        printf("线程创建失败,程序退出。\n");
        return -1;
    }
    var++;
    if (pthread_create(&pthid4, NULL, mainfunc4, NULL)!= 0)
    {
        printf("线程创建失败,程序退出。\n");
        return -1;
    }
    var++;
    if (pthread_create(&pthid5, NULL, mainfunc5, NULL)!= 0)
    {
        printf("线程创建失败,程序退出。\n");
        return -1;
    }
    printf("pthid1=%lu\n", pthid1);
    printf("pthid2=%lu\n", pthid2);
    printf("pthid3=%lu\n", pthid3);
    printf("pthid4=%lu\n", pthid4);
    printf("pthid5=%lu\n", pthid5);

    printf("等待子线程退出。\n");
    pthread_join(pthid1, NULL);
    printf("子线程1已退出。\n");

    pthread_join(pthid2, NULL);
    printf("子线程2已退出。\n");

    pthread_join(pthid3, NULL);
    printf("子线程3已退出。\n");

    pthread_join(pthid4, NULL);
    printf("子线程4已退出。\n");

    pthread_join(pthid5, NULL);
    printf("子线程5已退出。\n");
    return 0;
}

void *mainfunc1(void *arg)
{
    printf("我是%d线程\n",var);
    for (int ii = 0;  ii < 10; ++ii)
    {
        // a++;
         sleep(1);
        // printf("a = %d func1 sleep lsec ok.\n", a);
    }
    pthread_exit(0);    // 子线程退出,不影响主线程
}

void *mainfunc2(void *arg)
{
    printf("我是%d线程\n", var);
    for (int ii = 0;  ii < 10; ++ii)
    {
        // a++;
        sleep(1);
        // printf("a = %d func2 sleep lsec ok.\n", a);
    }
    pthread_exit(0);    // 子线程退出,不影响主线程
}

void *mainfunc3(void *arg)
{
    printf("我是%d线程\n", var);
    for (int ii = 0;  ii < 10; ++ii)
    {
        // a++;
        sleep(1);
        // printf("a = %d func3 sleep lsec ok.\n", a);
    }
    pthread_exit(0);    // 子线程退出,不影响主线程
}

void *mainfunc4(void *arg)
{
    printf("我是%d线程\n", var);
    for (int ii = 0;  ii < 10; ++ii)
    {
        // a++;
        sleep(1);
        // printf("a = %d func4 sleep lsec ok.\n", a);
    }
    pthread_exit(0);    // 子线程退出,不影响主线程
}

void *mainfunc5(void *arg)
{
    printf("我是%d线程\n", var);
    for (int ii = 0;  ii < 10; ++ii)
    {
        // a++;
        sleep(1);
        // printf("a = %d func5 sleep lsec ok.\n", a);
    }
    pthread_exit(0);    // 子线程退出,不影响主线程
}

这个代码就是创建线程,然后在每个函数中输出自己是第几个线程,按照这个代码来说我们输出的结果应该是一 一对应的。我们来看一下结果。

结果都是5,这里出现这种结果的原因就是你创建线程是按照顺序创建的,但是你的mainfunc()函数不一定是创建一个就输出一个,所以都是等主线程都执行完毕了,var这个时候已经等于5了,所以你最后输出的结果那肯定都是5。那么现在就来解决这个问题。 

 我们通过man pthread_create 可以看到这个函数的第四个参数是一个void *类型,这里引入一个强制类型转换的概念。

通常指针都是存地址,但是我这里我想传值进去,因为如果传地址那不就是和前面的全局变量没有什么区别了,所以这里我们要传值进去,就得强制类型转化一下。下面的这种强制类型转化很明显不可以,我们来看下报了什么错误

 我们先看第一个报错,告诉我们大小不同,我们知道不同操作系统下的指针大小是不一样的,64位下8字节。所以我们改一下。

 损失精度好办。

 ok,这样我们就解决了如何传值的问题了。那么回到一开始的传参,我们修改一下。

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

// 与客户端通信的主函数
void *mainfunc1(void *arg);
void *mainfunc2(void *arg);
void *mainfunc3(void *arg);
void *mainfunc4(void *arg);
void *mainfunc5(void *arg);

int main()
{
    /*
    // 不一样的强制类型转换
    int ii = 10;
    void *ptr1 = (void *)(long)ii;
    int jj = (int)(long)ptr1;

    long aa = 10;
    void *ptr2 = (void *)aa;
    long bb = (long)ptr2;
    */

    int var = 1;
    pthread_t pthid1, pthid2, pthid3, pthid4, pthid5;

    // 创建一个线程
    // pthread_create()第四个参数是void *,所以需要强制转化
    if (pthread_create(&pthid1, NULL, mainfunc1, (void *)(long)var)!= 0)
    {
        printf("线程创建失败,程序退出。\n");
        return -1;
    }
    var++;
    if (pthread_create(&pthid2, NULL, mainfunc2, (void *)(long)var)!= 0)
    {
        printf("线程创建失败,程序退出。\n");
        return -1;
    }
    var++;
    if (pthread_create(&pthid3, NULL, mainfunc3, (void *)(long)var)!= 0)
    {
        printf("线程创建失败,程序退出。\n");
        return -1;
    }
    var++;
    if (pthread_create(&pthid4, NULL, mainfunc4, (void *)(long)var)!= 0)
    {
        printf("线程创建失败,程序退出。\n");
        return -1;
    }
    var++;
    if (pthread_create(&pthid5, NULL, mainfunc5, (void *)(long)var)!= 0)
    {
        printf("线程创建失败,程序退出。\n");
        return -1;
    }
    printf("pthid1=%lu\n", pthid1);
    printf("pthid2=%lu\n", pthid2);
    printf("pthid3=%lu\n", pthid3);
    printf("pthid4=%lu\n", pthid4);
    printf("pthid5=%lu\n", pthid5);

    printf("等待子线程退出。\n");
    pthread_join(pthid1, NULL);
    printf("子线程1已退出。\n");

    pthread_join(pthid2, NULL);
    printf("子线程2已退出。\n");

    pthread_join(pthid3, NULL);
    printf("子线程3已退出。\n");

    pthread_join(pthid4, NULL);
    printf("子线程4已退出。\n");

    pthread_join(pthid5, NULL);
    printf("子线程5已退出。\n");
    return 0;
}

void *mainfunc1(void *arg)
{
    printf("我是%d线程\n", (int)(long)arg);
    for (int ii = 0;  ii < 10; ++ii)
    {
        // a++;
         sleep(1);
        // printf("a = %d func1 sleep lsec ok.\n", a);
    }
    pthread_exit(0);    // 子线程退出,不影响主线程
}

void *mainfunc2(void *arg)
{
    printf("我是%d线程\n",(int)(long)arg);
    for (int ii = 0;  ii < 10; ++ii)
    {
        // a++;
        sleep(1);
        // printf("a = %d func2 sleep lsec ok.\n", a);
    }
}

void *mainfunc3(void *arg)
{
    printf("我是%d线程\n", (int)(long)arg);
    for (int ii = 0;  ii < 10; ++ii)
    {
        // a++;
        sleep(1);
        // printf("a = %d func3 sleep lsec ok.\n", a);
    }
}

void *mainfunc4(void *arg)
{
    printf("我是%d线程\n", (int)(long)arg);
    for (int ii = 0;  ii < 10; ++ii)
    {
        // a++;
        sleep(1);
        // printf("a = %d func4 sleep lsec ok.\n", a);
    }
}

void *mainfunc5(void *arg)
{
    printf("我是%d线程\n", (int)(long)arg);
    for (int ii = 0;  ii < 10; ++ii)
    {
        // a++;
        sleep(1);
        // printf("a = %d func5 sleep lsec ok.\n", a);
    }
}

 再来看一下结果。

 这样就都分开了,顺序不一样是正常的,因为编译器的优化问题,所以顺序不一样很正常,我们只需要知道结果是每一个线程都知道了自己准确的编号了。

还有一个解决方案那就是在每一个var++前面sleep(1);但是这样会耗时间。

总结,主要是说一下pthread_create()函数的参数传递。 

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Linux 中,你可以通过不同的方法多次传递参数线程函数。下面是一些常见的方法: 1. 使用结构体:创建一个结构体,将需要传递参数封装在结构体中,然后将结构体的地址作为参数传递线程函数。线程函数可以通过解引用结构体指针来获取传递参数。 ```c #include <stdio.h> #include <pthread.h> // 定义结构体 typedef struct { int value1; int value2; } ThreadArgs; // 线程函数,接收结构体参数 void* threadFunc(void* arg) { ThreadArgs* args = (ThreadArgs*)arg; int value1 = args->value1; int value2 = args->value2; printf("Thread function received values: %d, %d\n", value1, value2); // 线程操作... pthread_exit(NULL); } int main() { pthread_t tid; ThreadArgs args = { 42, 10 }; // 创建结构体并初始化参数 // 创建线程,并传递结构体参数 if (pthread_create(&tid, NULL, threadFunc, &args) != 0) { printf("Failed to create thread\n"); return 1; } // 等待线程结束 pthread_join(tid, NULL); return 0; } ``` 2. 使用数组:将需要传递参数存储在数组中,并将数组的地址作为参数传递线程函数。线程函数可以通过访问数组元素来获取传递参数。 ```c #include <stdio.h> #include <pthread.h> // 线程函数,接收数组参数 void* threadFunc(void* arg) { int* args = (int*)arg; int value1 = args[0]; int value2 = args[1]; printf("Thread function received values: %d, %d\n", value1, value2); // 线程操作... pthread_exit(NULL); } int main() { pthread_t tid; int args[] = { 42, 10 }; // 创建数组并初始化参数 // 创建线程,并传递数组参数 if (pthread_create(&tid, NULL, threadFunc, args) != 0) { printf("Failed to create thread\n"); return 1; } // 等待线程结束 pthread_join(tid, NULL); return 0; } ``` 无论使用结构体还是数组,都要确保传递参数线程函数中正确地访问和使用。同时,需要注意传递参数的生命周期,确保参数线程使用完毕之前保持有效。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值