线程的基础概念与线程创建

10 篇文章 0 订阅
本文介绍了线程的基础概念,包括进程与线程的区别,线程的三种实现方式以及优缺点。重点讲解了线程的创建,如pthread_create()函数及其参数,以及线程的结束、等待和取消。此外,还探讨了线程参数传递的注意事项和线程间数据共享的特点。
摘要由CSDN通过智能技术生成

线程的基础概念与线程创建

我们在之前了解了什么是进程,那么什么是线程呢?

  • 进程:执行中的程序,程序是存储在磁盘上的可执行文件,是静态的概念,而进程是动态的概念,进程可以看作一组有序指令+数据+资源的集合。
  • 线程:我们将线程看作轻量级的进程,线程是进程内部的一条执行序列,一个进程中至少有一条线程,也就是main主函数所代表的执行序列,称之为主线程,通过可以通过线程库创建线程(函数线程)。

 

线程的实现方式分为三种:

①:用户级线程:线程的实现在用户态实现,对于内核,只能识别其是一个进程。

线程的管理由用户级实现,内核实现简单,不需要实现线程。

优点:切换速度快

缺点:1.用户代码复杂     2.当一条线程阻塞,会造成整个进程阻塞

 

②:内核级线程:(Linux目前支持)线程的实现在内核态实现,线程创建,调度,销毁等管理是由操作系统支持的。

优点:1.用户代码简单     2.一条线程阻塞,操作系统会立马切换到另一条线程,整个进程不会阻塞。

缺点:1.内核实现复杂,需要支持多线程。    2.线程切换效率低,线程每次切换必须陷入内核

 

③:混合级线程:结合上述两个,集齐优点

我们用图来直观表示其三者的区别:

 

接下来我们看一看线程的创建(也就是线程库的使用):

①:线程创建函数:pthread_create()

函数原型:int pthread_create(pthread_t *id, pthread_attr_t *attr, \

void *(*pthread_fun)(void *), void *arg);

我们来看一看其中的参数的意义:

  • id:create函数返回创建的线程的id,通过第一个参数“id”进行接收
  • attr:传入线程的属性,默认属性传NULL
  • pthread_fun:线程库创建的函数线程(相当于创建的线程需要执行的函数)
  • arg:传递给函数线程所执行的函数的实参
  • 返回值:成功返回0,失败返回错误码

②:线程的结束函数:pthread_exit

函数原型:int  pthread_exit(void  *reval);

这个函数会结束当前线程

  • reval:可以通过这个参数将线程结束时像传递的信息传递出来,可以通过pthread_join()函数中的val参数进行接收。
  • 返回值:成功返回0,失败返回错误码

③:等待线程结束的函数:pthread_join

int  pthread_join(phtread_t   tid,  void  **val);

调用方会阻塞,直到等待的tid号线程结束,获取结束的线程的退出信息

  • tid:线程的id
  • val:将函数线程传递出的信息,可用这个输出参数进行接收
  • 返回值:成功返回0,失败返回错误码

④:主动结束函数:pthread_cancel

int    pthread_cancel(pthread_t  tid);

线程可以通过调用pthread_cancel函数来请求取消同一进程中的其他线程

这个函数会根据传入的tid,直接发送取消信号给这个线程。

  • tid:线程的id
  • 返回值:成功返回0,失败返回错误码

 

最后我们这里需要注意一点,pthread_create()线程创建的时候,第四个参数arg的传参方式:

分为两种:

①:值传递方式:

  • 只能应用于小于等于4字节的数据,因为强转前其本质是个指针,只有4字节大小空间
  • 我们传参时需要先将变量数值强转为void *,进行传值

②:地址传递方式:

  • 将变量地址转化为void *   很危险
  • 函数线程中通过传递对变量的修改,会造成主线程值也随之修改
  • 而主线程对变量的修改,也会创造函数线程中值的修改

③:为了安全,函数线程一开始,就将传进来的值自己拷贝一份,之后修改都修改自己拷贝的值

 

最后,我们来看一看线程的数据共享并与进程做对比:

我们首先要知道进程哪些数据是共享的,哪些是不共享的:

我们在之前对fork的底层实现过程进行过总结,可以知道fork出的子进程对父进程的已打开文件的控制结构file_struct会通过copy_files()函数进行拷贝,所以父子进程会共享文件描述符,以及文件偏移量,而全局数据,栈区数据,堆区数据是不共享的。

我们用下面的这张图来直观表示:

 

而线程的哪些数据是共享的,哪些是不共享的:

我们知道同一个进程中每个线程都共享进程的所有资源,除了栈区。

所以结论就是:同一个进程中每个线程都有自己独立的栈区,而其他资源,比如全局数据,堆区数据,PCB(文件表数组)都是共享的。所以线程间通讯可以很简单的通过全局,堆区,文件来通讯。

我们用下面的这张图来直观表示:

至此,线程基础知识了解完毕。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值