《程序员的自我修养 — 链接,装载与库》这本书被很多人推荐,翻了一下,好像确实是一本很有意思的书,值的推荐。我会陆陆续续把读书笔记写在这里。
这是第二部分,目录如下:
- 入口函数和程序的初始化
1. 入口函数_start 函数和程序的初始化
- 从bash上面fork出一个进程,然后去执行入口函数(_start 函数)。
- 进行初始化和运行环境的初始化,包括堆,I/O,线程,全局变量。
- 入口函数初始化之后,调用main函数,并把argc,argv等参数传递给main函数,然后去执行。
- main函数执行完毕之后,返回到入口函数。包括全局变量的析构,堆销毁,关闭I/O。然后进行系统调用结束进程。
2. 内核级线程和用户级线程
简单的来说,用户级的多线程在内核看来是一个进程(尽管它里面有多个线程),如果一个线程在io(或者被阻塞)那么这个进程将被挂起来。也就说其他的线程也无法获得cpu。
内核级的线程,如果一个线程阻塞,那么其他的线程依然可能获得cpu。
在linux下面通过pthread_create 创建的线程是内核级的线程。在调用pthread_create函数的时候,调用了clone的系统调用。
( PS : 查了一下 NPTL(Native POSIX Thread Library)实现中,用户创建的线程和内核中调度实体的关系是1:1。其他线程库的实现,可以支持M:N。)
cat /proc/[pid]/status #这是查看进程状态很好的一个命令
#里面有一个tpid的选项和一个Threads的参数
#表示的了当前进程创建的线程组id和线程数目。
#如果你创建的线程,os感知不到,那就是用户线程
- 又想到一个问题 fork / vfork /clone 的区别
关于fork和vfork的区别 ://www.greatytc.com/p/bc0ef5a911a7- vfork 子进程先执行
- vfork 完全和父进程共享内存,包括堆、BSS、初始化非0数据区等区域。
- clone 系统调用是fork()的推广形式,它允许新进程指定具体需要与父进程共享哪些元素,如存储空间、文件描述符、信号处理程序等。是否需要阻塞父进程等,所以,比fork更加灵活。