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

本节将给出 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
阅读更多:   C语言 , Linux笔记
添加新评论

icon_redface.gificon_idea.gificon_cool.gif2016kuk.gificon_mrgreen.gif2016shuai.gif2016tp.gif2016db.gif2016ch.gificon_razz.gif2016zj.gificon_sad.gificon_cry.gif2016zhh.gificon_question.gif2016jk.gif2016bs.gificon_lol.gif2016qiao.gificon_surprised.gif2016fendou.gif2016ll.gif