9

linux C语言多线程编程,如何传入参数,如何获得返回值

 3 years ago
source link: https://blog.popkx.com/linux-c-multi-thread-programming-how-to-input-parameters-and-how-to-aquire-return-values/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

linux C语言多线程编程,如何传入参数,如何获得返回值

发表于 2018-08-07 22:08:08   |   已被 访问: 1,646 次   |   分类于:   C语言 , Linux笔记   |   暂无评论

本节将给出 linux 下 c 语言多线程编程的例子 demo。

在 linux 下实现多线程,关键函数是 pthread_create 函数。

  • 函数简介
      pthread_create是UNIX环境创建线程函数
  • 头文件
      #include<pthread.h>
int pthread_create(
    pthread_t *restrict tidp,
    const pthread_attr_t *restrict_attr ,
     void*(*start_rtn)(void*), 
     void *restrict arg
);
  • 返回值
      若成功则返回0,否则返回出错编号
  • 参数
      第一个参数为指向线程标识符的指针。
      第二个参数用来设置线程属性。
      第三个参数是线程运行函数的地址。
      最后一个参数是运行函数的参数。

下面给出一段 demo

#include "stdio.h"
#include "pthread.h"
#include "unistd.h"

void* myPrint()
{
    int i = 5;
    while(i--){
        sleep(1);
        printf("this is from myPrint\n");
    }
}

int main()
{
    pthread_t pid;
    int res = pthread_create(&pid, NULL, myPrint, NULL);
    sleep(6);

    return 0;
}

因为pthread并非Linux系统的默认库,所以在编译时注意加上-lpthread参数,以调用静态链接库。

$ gcc -pthread -o test.out test.c
$ ./test.out 
this is from myPrint
this is from myPrint
this is from myPrint
this is from myPrint
this is from myPrint

pthread_join 函数

上一部分给出的例子,在主函数中有一句 sleep(6);,而 myPrint 函数只需 5 秒就可以执行完毕,所以打印出了 5 行 this is from myPrint。如果将主函数中的sleep(6);注释掉,会发生什么呢?

...
int main()
{
    pthread_t pid;
    int res = pthread_create(&pid, NULL, myPrint, NULL);
    //sleep(6);

    return 0;
}

编译执行,发现什么也没输出。myPrint 函数并没有阻塞程序退出,这不是我期望的。这时,可以使用 pthread_join 函数。

  • 函数简介
    函数pthread_join用来等待一个线程的结束。
  • 函数原型为:
int pthread_join(pthread_t __th, void **__thread_return);
  • 参数:
      第一个参数为被等待的线程标识符
      第二个参数为一个用户定义的指针,它可以用来存储被等待线程的返回值。
  • 注意
    这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源被收回。如果执行成功,将返回0,如果失败则返回一个错误号。

这个函数是阻塞性的,它可以确保线程完整运行。而且还可以获取函数的返回值,下面是一个 demo。

#include "stdio.h"
#include "pthread.h"
#include "unistd.h"

void* myPrint()
{
    int i = 5;
    while(i--){
        sleep(1);
        printf("this is from myPrint\n");
    }
}

int main()
{
    pthread_t pid;
    int res = pthread_create(&pid, NULL, myPrint, NULL);
    //sleep(6);
    pthread_join(pid, NULL);
    return 0;
}

编译执行,

$ gcc -pthread -o test.out test.c
$ ./test.out 
this is from myPrint
this is from myPrint
this is from myPrint
this is from myPrint
this is from myPrint

发现myPrint线程完毕后才退出,如何预期。

添加参数,获取返回值

pthread_create 函数的第四个参数就是输入参数的地方,只不过是 void* 型,需要类型转换一下。返回值则可以用 pthread_join 函数的第二个参数返回,也需要转换一下,下面是 demo:

没有什么难度,主要是建立了 DATA 结构体类型,用于转换数据。

#include "stdio.h"
#include "pthread.h"
#include "unistd.h"

typedef struct __DATA
{
    int     vint;
    long    vlong;
    double  vdouble;
}DATA;

void* myPrint(void* param)
{
    DATA* data = (DATA*)param;

    printf("this is from myPrint\n");
    printf("param1: %d, param2: %ld, param3: %f\n",
            data->vint, data->vlong, data->vdouble);

    return (void*)"xrkzn.cn";
}

int main()
{
    pthread_t pid;

    int param1 = 11;
    long param2 = 222;
    double param3 = 333.44;

    DATA data = {0};
    data.vint = param1;
    data.vlong = param2;
    data.vdouble = param3;

    pthread_create(&pid, NULL, myPrint, &data);

    void* rtn;
    pthread_join(pid, &rtn);

    printf("myPrint return: %s\n", (char*)rtn);

    return 0;
}

编译执行,一切符合预期。

$ gcc -pthread -o test.out test.c
$ ./test.out 
this is from myPrint
param1: 11, param2: 222, param3: 333.440000
myPrint return: xrkzn.cn

Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK