
对应的system call:
asmlinkage long sys_getpid(void)
1614 {
1615 return current->tgid
1616 }
tgid = thread group id
/////////////////////////////////////////////////////////////////////////
gettid:取得线程id,如果是process,其实就等于getpid:
#define gettid() syscall(__NR_gettid)
对应的system call:
/* Thread ID - the internal kernel "pid" */
1761 asmlinkage long sys_gettid(void)
1762 {
1763 return current->pid
1764 }
getgid:取得group id,就是user的group id
和用id命令得到的group id是一回事:
bash-3.1$ id
uid=3013(xxx) gid=300(xxxx) groups=300(xxxx),301(platform),505(fpgadrv),9022(gsm)
对于一个thread来说,在kenerl中可以看到他的process id(tgid),还可以看到他的thread id(pid)。
执行一个 copy,但是只要任何修改,都造成分裂如,修改了chroot,写memory,mmap,sigaction 等。
p1 是一个 task_struct, p2 也是一个 task_struct. linux内核的调度器只认得task_struck (不管你是进程还是线程), 对其进行调度。
p2 的task_struck 被创建出来后,也有一份自己的资源。但是这些资源会短暂的与p1 相同。
进程是区分资源的单位,你的资源是我的资源,那从概念上将就不叫进程。
其他资源都好分配,唯一比较难的是内存资源的重新分配。
非常简单的程序,但是可以充分说明 COW。
结果:10 ->20 ->10
COW 是严重依赖于CPU中的MMU。CPU如果没有 MMU,fork 是不能工作的。
在没有mmu的CPU中,不可能执行COW 的,所以只有vfork
vfork与fork相比的不同
P2没有自己的 task_struct, 也就是说P1 的内存资源 就是 P2的内存资源。
结果 10,20,20
vfork:
vfork 执行上述流程,P2也只是指向了P1的mm,那么将这个vfork 放大,其余的也全部clone,共同指向P1,那么就是线程的属性了。
phtread_create ->Clone()
P1 P2 在内核中都是 task_struct. 都可以被调度。共享资源可调度,即线程。 这就是线程为什么也叫做轻量级进程
不需要太纠结线程和进程的区别。
4651 : TGID
4652, 4653 tid 内核中 task_struct 真正的pid
linux 总是白发人 送 黑发人。如果父进程在子进程推出前挂掉了。那么子进程应该怎么办?
p3 ->init, p5 ->subreaper
每一个孤儿都会找最近的火葬场
可以设置进程的属性,将其变为subreaper,会像1号进程那样收养孤儿进程。
linux的进程睡眠依靠等待队列,这样的机制类似与涉及模式中的订阅与发布。
睡眠,分两种
每一个进程都是创建出来的,那么第一个进程是谁创建的呢?
init 进程是被linux的 0 进程 创建出来的。开机创建。
父进程就是 0 号进程,但在pstree,是看不到0进程的。因为0进程创建子进程后,就退化成了idle进程。
idle进程是 linux内核里,特殊调度类。 所有进程都睡眠停止 ,则调度idle进程,进入到 wait for interrupte 等中断。此时 cpu及其省电,除非来一个中断,才能再次被唤醒。
唤醒后的任何进程,从调度的角度上说,都比idle进程地位高。idle是调度级别最最低的进程。
0 进程 一跑,则进入等中断。一旦其他进程被唤醒,就轮不到 0进程了。
所有进程都睡了,0就上来,则cpu需要进入省电模式
到了linux 2.6, glibc中有了一种新的pthread线程库--NPTL(Native POSIX Threading Library). NPTL实现了前面提到的POSIX的全部5点要求. 但是, 实际上, 与其说是NPTL实现了, 不如说是linux内核实现了.在linux 2.6中, 内核有了线程组的概念, task_struct结构中增加了一个tgid(thread group id)字段. 如果这个task是一个"主线程", 则它的tgid等于pid, 否则tgid等于进程的pid(即主线程的pid).在clone系统调用中, 传递CLONE_THREAD参数就可以把新进程的tgid设置为父进程的tgid(否则新进程的tgid会设为其自身的pid).
类似的XXid在task_struct中还有两个:task->signal->pgid保存进程组的打头进程的pid、task->signal->session保存会话打头进程的pid。通过这两个id来关联进程组和会话。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)