多线程:创建、等待、终止、分离详解

目录

一、线程创建

二、线程等待

三、多线程的创建

四、线程终止

五、线程分离


在Linux下创建线程依赖第三方库
因为在Linux中只有轻量级进程,因此整个第三方库只是一个对轻量级进程的封装
也因此,Linux自带一个叫做pthread的库
因此,创建线程的代码:
1、需要#include <pthread.h>
2、编译链接时,需加上库名:-lpthread

一、线程创建

每个线程有自己的栈、堆空间的理解:
一个在main函数栈中创建的变量,其他线程是可以看见的
因为地址资源共享,地址空间共享,这就会导致混淆、混乱
可能属于主线程的数据会被子线程修改,不具有独立性
因此,一般的线程的创建,各自线程的变量不要在栈空间中创建
而是在堆中创建,因为堆是需要地址才可以访问
再将该地址交给对应线程维护
如此,一个线程就相当于都有了一个对应的堆空间

线程创建函数:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                   void *(*start_routine)(void *), void *arg);//这个函数是由第三方库pthread提供的

第一个参数:输出型参数,其实对无符号long长整型的封装,本质是虚拟地址
第二个参数:设为nullptr即可
第三个参数:一个函数指针,需要输入一个函数的地址,新线程会执行这部分代码
因为函数的返回值是void*,因此要获取void*的数据,就要使用void**的指针
而pthread_join等待函数的第二个参数就是void**,因此该参数就是为了获取执行函数的返回值
(void不能直接定义变量,但是void*可以,一个指针变量,有空间;可以理解为类似int的类型)
主线程可以通过这个参数,获取新线程的执行情况
当子线程崩溃时,进程也会崩溃
因此,子线程函数的返回值只考虑正确的情况,不考虑异常
同时,线程函数的返回值也是一个void*类型,因此可以设计任意对象的返回值

第四个参数:该参数传给第三个参数的函数形参,作为实参
第四个参数是void*类型,因此可以传递任意类型的对象,例如类对象
返回值:成功返回0;错误返回错误码

二、线程等待

int pthread_join(pthread_t thread, void **retval);//用于主线程等待线程的退出

第一个参数:要等待的线程 ID。
第二个参数:输出型参数,获取线程执行函数返回值
返回值:0等待成功

三、多线程的创建

1、线程id
2、执行方法
3、第四个参数可以传线程名
4、join
5、释放堆空间
注意:线程独立性

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <unistd.h>
#include <vector>

void* thread_run(void* arg)
{
    sleep(1);
    std::cout << (char*)arg << ": is runing ... " << std::endl;  
    return (void*)1111;
}

int main()
{
    std::vector<pthread_t> tids;
    for(int i = 0; i<10; i++)
    {
        tids.push_back(i);
        char* name = new char[128];
        pthread_create(&tids[i], nullptr, thread_run, (void*)name);
    }
    
    //等待
    int64_t* return_val;
    for(pthread_t tid : tids)
    {
        pthread_join(tid, (void**)return_val);
        std::cout << "thread-" << tid << "quit" << std::endl; 
    }


    return 0;
}

四、线程终止

1、线程函数return,线程结束
2、主线程退出,进程结束,所有线程结束;因此主线程最好最后退出
3、exit()函数是进程退出,不是线程退出,因此任意子线程调用exit()函数,会导致进程直接退出
4、void* pthread_exit(void *retval )函数:线程退出,参数获取线程执行函数返回值
5、int pthread_cancle(pthread_t thread )函数:取消线程,参数线程id;返回值-1

因此,线程的终止有三种情况:函数ureturn、退出、取消三种。

五、线程分离

线程执行完毕,自己退出,不用join等待

int pthread_detach(pthread_t thread);//线程分离
pthread_t pthread_self(void);//获取当前线程id

如果线程已经分离,却依旧等待,就会出错,等待函数返回值为22
但是即使线程分离,如果子线程崩溃,依旧会导致进程崩溃
因为虽然是分离,但是实际上还是处于一个进程内部,共享同一个地址空间
可以子线程自己分离自己,也可以由主线程分离其他子线程

C++多线程:
C++11的多线程就是对Linux的原生库函数的封装
事实上,Linux环境下的所有语言,例如C、java、python等都是对原生库函数的封装,这是语言跨平台的本质,注意,是快平台,而不是跨环境。


 

  • 26
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

二十5画生

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

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

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

打赏作者

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

抵扣说明:

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

余额充值