linux下的线程thread

何为线程?

线程是一种轻量级的进程,一个进程至少包含 1 个线程,也可以包含多个线程,所有线程共享进程的资源,各个线程也可以拥有属于自己的私有资源。其实,进程仅负责为各个线程提供所需的资源,真正执行任务的是线程,而不是进程。

如何创建一个线程?

POSIX(可移植操作系统接口) 标准中规范了与多线程相关的系统接口。我们在 Linux 系统上编写多线程程序,只需在程序中引入<pthread.h>头文件,调用该文件中包含的函数即可实现多线程编程,<pthread.h> 头文件中只包含各个函数的声明部分,具体实现位于 libpthread.a 库中,在编译的时候需要链上这个静态库。

线程创建的过程,就是先调用pthread_create创建一个新线程,然后pthread_join,等待线程处理,最终就是终止线程。

我们先来学习一下几个关键的函数,man一下pthread_create这个函数,可以看到,这个函数有四个入参和一个返回int型返回值

int pthread_create(

        pthread_t *thread,

        const pthread_attr_t *attr,

        void *(*start_routine) (void *),

        void *arg);

参数1:放入一个线程标识符的地址

参数2:是对线程属性的修改,一般不修改,直接给null,pthread_create() 函数会采用系统默认的属性值创建线程。

参数3:以函数指针的方式指明新建线程需要执行的函数

参数4:线程处理函数的入参,要传入处理的参数,可以给null

返回值:创建成功则返回0,非0就表示不成功。


再man一下pthread_join这个函数,他是两个参数,返回值也是一个int型

int pthread_join(pthread_t thread, void **retval);

参数1:要等待的线程的线程标识符

参数2:保存线程处理函数的返回值,注意是二级指针

返回值: 返回0表示成功,非0表示不成功

pthread_join() 函数会一直阻塞调用它的线程,直至目标线程执行结束(接收到目标线程的返回值),阻塞状态才会解除。并且一个线程执行结束的返回值只能由一个 pthread_join() 函数获取,当有多个线程调用 pthread_join() 函数获取同一个线程的执行结果时,哪个线程最先执行pthread_join() 函数,执行结果就由那个线程获得,其它线程的 pthread_join() 函数都将执行失败。


此处给出一个示例代码,读者可以参考学习

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

//定义线程要执行的函数,
//arg为接收线程传递过来的数据

void *Thread1(void *arg)
{
    printf("hello world\n");
    return "thread1 finish";
}
void* Thread2(void* arg)
{
    printf("hi world\n");
    return "thread2 finish";
}

int main()
{
    int res;    //存放创建是否成功的返回值
    pthread_t mythread1, mythread2;  //定义两个线程的标识符
    void* thread_result;  //定义一个void *的指针,后面可以给他赋任意类型的指针
    /*创建线程(create)
      &mythread:要创建的线程
      NULL:不修改新建线程的任何属性
      ThreadFun:新建线程要执行的任务
      NULL:不传递给 ThreadFun() 函数任何参数
  
      返回值res为 0 表示线程创建成功,反之则创建失败。
    */
    res = pthread_create(&mythread1, NULL, Thread1, NULL);
    if (res != 0) 
    {
        printf("线程创建失败\n");
        return -1;
    }

    res = pthread_create(&mythread2, NULL, Thread2, NULL);
    if (res != 0)
    {
        printf("线程创建失败\n");
        return -1;
    }
    /*
      等待线程(join)
      mythread*:指定等待的线程
      &thead_result:接收 ThreadFun() 函数的返回值,或者接收 pthread_exit() 函数指定的值
  
      返回值 res 为 0 表示函数执行成功,反之则执行失败。
    */
    res = pthread_join(mythread1, &thread_result);
    //输出线程执行完毕后返回的数据
    printf("%s\n", (char*)thread_result);
   
    res = pthread_join(mythread2, &thread_result);
    printf("%s\n", (char*)thread_result);
    printf("main thread finish\n");
    return 0;
}

编译的时候需要加上-lpthread这个静态库,才能编译通过。(关于静态库和动态库的知识可以看我另一篇博文,链接如下)

编译的命令如下,可以看到运行的结果,没有问题。

有一个需要注意的点,上面这个程序,这个进程中,我们虽然自己只是创建了两个线程,但实际上是有三个线程,另外一个是本就存在的主线程,就像文章开头所说的,进程不办事,办事的都是线程,所以一个进程,最初肯定是有一个线程在的。

从程序中还可以看出的是, pthread_create() 函数成功创建的线程会自动执行指定的函数,不需要手动开启,此外,为了防止主线程提前退出,而没来得及执行其他线程,我们一般会在主线程中加上sleep延时一下。

终止线程执行

终止线程执行的办法呢,有三种。

第一种自动终止,就是不去人为干预,线程运行完了自己就退出了,

第二种pthread_exit(),其实和return有点类似,但是pthread_exit()是专门用来退出一个线程的,不会影响其它线程的执行,而return是会影响到其他线程的,就比如在主线程中用了return,那整个程序就都退出了,包括其他的线程。使用的方法如下。

void *ThreadFun(void *arg)
{
    //终止线程的执行
    pthread_exit("线程终止成功"); //返回的字符串存储在常量区,并非当前线程的私有资源
    printf("线程终止失败");//此语句不会被线程执行
}

第三种pthread_cancel()其实是一种信号终止,他具体是通过一个线程向另一个线程(需要在同一个进程内)发送终止信号来实现终止线程的,使用的方法就是在pthread_cancel()的括号中加上想要终止的线程标识符就行。

int pthread_cancel(pthread_t thread);
//返回值是0说明终止成功

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

翔在天上飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值