Linux上C语言如何获取线程的返回值

一、线程的三个重要的应用程序接口(API)

1.1 线程的创建

#include <pthread.h>
int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);

pthread_create成功返回0。

  1. tidp 指向的内存单元被设置为新创建线程的线程ID。
  2. attr 参数用于定制各种不同的线程属性,暂可以把它设置为 NULL,以创建默认属性的线程。(工作中也多用NULL)
  3. 新创建的线程从 start_rtn(函数指针)函数的地址开始运行,该函数只有一个无类型指针参数 arg
  4. 如果需要向 start_rtn 函数传递的参数不止一个,那么需要把这些参数放到一个结构中,然后把这个结构的地址作为 arg 参数传入。

1.2 线程的退出

单个线程可以通过以下三种方式退出,在不终止整个进程的情况下停止它的控制流:

  1. 线程只是从启动例程中返回,返回值是线程的退出码
  2. 线程可以被同一进程中的其他线程取消
  3. 线程调用pthread_exit
#include <pthread.h>
int pthread_exit(void *rval_ptr);

rval_ptr 是一个无类型指针,与传给启动例程的单个参数类似。进程中的其他线程可以通过调用 pthread_join 函数访问到这个指针。

1.3 线程的等待

#include <pthread.h>
int pthread_join(pthread_t thread, void **rval_ptr);
// 返回:若成功返回0,否则返回错误编号

调用这个函数的线程将一直阻塞,直到指定的线程调用pthread_exit、从启动例程中返回或者被取消。

  1. 如果例程只是从它的启动例程返回,rval_ptr 将包含返回码。
  2. 如果线程被取消,由 rval_ptr 指定的内存单元就置为PTHREAD_CANCELED。

可以通过调用pthread_join自动把线程置于分离状态,这样资源就可以恢复。如果线程已经处于分离状态,pthread_join 调用就会失败,返回 EINVAL。

如果对线程的返回值不感兴趣,可以把 rval_ptr 置为 NULL 。在这种情况下,调用 pthread_join 函数将等待指定的线程终止,但并不获得线程的终止状态。

  • 在 Linux 的 C 语言多线程环境中,启动例程通常指的是主线程(Main Thread)中的入口函数。在多线程程序中,主线程是程序的起点,它负责创建和管理其他线程,并在程序执行完成后终止整个进程。

  • 在 C 语言中,主线程的入口函数通常是 main 函数。main 函数是程序的入口点,当程序启动时,操作系统会调用 main 函数作为程序的起点。在多线程程序中,主线程的 main 函数会负责创建其他线程,分配资源,执行逻辑代码,并最终等待其他线程执行完成后终止整个进程。

  • 例程(routine)通常指的是一段执行特定任务的代码块或函数。在多线程环境中,每个线程都有自己的例程,用于定义线程要执行的任务。主线程的例程就是 main 函数,而其他线程的例程可以是通过线程创建函数(如 pthread_create)传入的函数指针,用于定义线程要执行的任务。

  • 总的来说,在 Linux 的 C 语言多线程环境中,启动例程指的是主线程的入口函数 main,而例程指的是线程要执行的任务代码块或函数。主线程的 main 函数负责创建其他线程,并启动线程执行各自的例程

二、让线程返回int类型的值

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

void* fun1(void *arg)
{
		//static(全局变量): 保证函数调用结束后,变量值还在
        static int ret = 10;

        printf("t1:%ld thread is create\n", (unsigned long)pthread_self());
        printf("t1: %d\n", *((int*)arg));
    	
    	// 3.退出线程函数
        pthread_exit((void *)&ret);//pthread_join可以通过其第二个参数访问这个指针
}


int main()
{

        //int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
        int ret;
        int param = 100;
        pthread_t t1;

        int *pret = NULL;

        //1.创建线程
        //                       线程属性 线程函数 线程函数参数
        ret = pthread_create(&t1, NULL, fun1, (void*)&param);

        if(ret == 0){
                printf("main:create t1 success\n");
        } else {
                perror("why t1 fail");
        }

        printf("main:%ld\n", (unsigned long)pthread_self());//打印主线程ID

        //2.等待线程函数退出
        pthread_join(t1, (void**)&pret);//等待线程结束,防止进程结束,线程还未执行完毕

		//4.输出线程int返回值
        printf("main: pret=%d\n", *pret);

        return 0;
}

二、让线程返回字符串(char*)类型的值

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

void* fun1(void *arg)
{
        static char* p = "t1 run out";//static(全局变量): 保证函数调用结束后,变量值还在

        printf("t1:%ld thread is create\n", (unsigned long)pthread_self());
        printf("t1: %d\n", *((int*)arg));

        //3.退出线程函数 返回返回值
        pthread_exit((void *)p);//pthread_join可以通过其第二个参数访问这个指针
}


int main()
{

        //int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
        int ret;
        int param = 100;
        pthread_t t1;

        char *pret = NULL;

        //1.创建线程
        //                       线程属性 线程函数 线程函数参数
        ret = pthread_create(&t1, NULL, fun1, (void*)&param);

        if(ret == 0){
                printf("main:create t1 success\n");
        } else {
                perror("why t1 fail");
        }

        printf("main:%ld\n", (unsigned long)pthread_self());//打印主线程ID

        //2.等待线程
        pthread_join(t1, (void**)&pret);//等待线程结束,防止进程结束,线程还未执行完毕
		
		//4.输出线程字符串返回值
        printf("main: pret=%s\n", pret);

        return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值