
"没有人会一直活在过去,除非他的生命定格在那一天。"
一个程序的执行路线上,叫做线程。
更准确的定义是:线程无非是"一个进程内部的控制序列".
①一个进程至少有一个执行流(线程);
②线程本质上是在进程内部运行的,享用同一块进程地址空间(这里暂且这样理解);
③线程的资源(进程地址空间),本质上是经由进程进行合理分配。
①创建一个线程,肯定要比创建一个进程损耗的代价要小。
②线程存在调度切换,但比进程间切换做的工作要小。
③线程占用的资源更少。
④可以充分利用处理器进行“并行”处理......
①性能损失:太多的线程,对于有限处理器进行来回切换,可能会造成较大性能损失。
②健壮性降低:引发 线程安全问题。
③缺乏访问控制;编写与调试一个多线程程序比单线程程序困难得多 .......
一旦分支线程出现异常,触发信号,进而整个进程也会崩溃。
文件描述符、每个信号的处理方法、用户id和组id
线程虽然共享资源,但也拥有一部分自己私有的部分。
线程id 、独立的栈、寄存器.......
以计算加密为主的;
IO密集型:刷新磁盘 访问数据库......
这里就要更新一下,之前对进程概念的解释。
它不浅显地认为,是一个运行起来的程序。也不是创建PCB,链接入调度队列,建立进程地址空间,建立页表与映射关系.....
站在系统层面上;
进程是资源分配的基本实体(单位)
线程是调度的基本单位

CPU是怎样识别出进程和线程的?
不能!但根本不用识别!因为进程不是由一个一个task_struct标识的。CPU眼中只有执行流。
因此,在认知层面上,也叫做轻量级进程。
如何理解linux下不存在多线程?
当线程足够多的时候,操作系统需要管理线程!(先描述,再组织)......必然需要再搭建一套,和进程类似的控制块!因此,为了简化设计,所以复用了进程管理的逻辑,进行线程管理。

一般在32位系统下的,用的是二级页表。64位机器则用的是多级页表。
通过分隔比特位,去查寻每个页表的位置。
主要是由集成 在CPU内部的 MMU单元硬件完成映射! (软硬件结合)
我们知道,Linux并没有真正意义的线程,所以也没有提供真正意义上与线程有关的系统调用接口!
但也提供了,原生线程库的方案。
注意:linux不提供线程库,所以编译的时候带上 -lpthread

#include
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
thread:返回线程ID
attr:线程属性,一般设置NULL(默认)
start_routine:函数指针,线程启动时执行的函数
arg:传给启动函数的参数


同进程等待同理,也需要知道,完成的任务的程度。
#include
int pthread_join(pthread_t thread, void **retval);
thread:线程ID
retavl:执行结果(类似退出码)
这里只讨论,线程正常终止!
#include
void pthread_exit(void *retval);
return xxx;
#include
int pthread_cancel(pthread_t thread);
我们分别用创建的三个线程,打印一句话。


我们通过获取进程 的pid ppid;

如果要获取 线程的id,库里提供了一个函数
#include
pthread_t pthread_self(void);

- //查看线程 lwp
- ps -aL
但线程id 看起来更像是地址;


因此,由pthread库提供的 线程id 实质上就是进程地址空间上 mmap区域的地址。
内核区别线程 在于 LWP
而用户区(提供接口) 线程id
如果不关心线程的返回值
join是一种负担,这个时候,我们可以告诉系统,当线程退出时,自动释放线程资源。
#include
int pthread_detach(pthread_t thread);



对于pthread_cancel而言,很少用从来去 取消它 主线程。一般都会去用作 处理一个进程中的分支线程
①进程与线程的概念区别。
②线程的优缺点,以及适用场所
③POSIX库 提供的线程函数。
本篇就到这里结束了,感谢你的阅读!
祝你好运~
