




已阅读5页,还剩4页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
关于Linux的线程与进程学院:计算机科学学院班级:计科10904班学号:201110043姓名:王成龙一、什么是进程直观点说,保存在硬盘上的程序运行以后,会在内存空间里形成一个独立的内存体,这个内存体有自己的地址空间,有自己的堆,上级挂靠单位是操作系统。操作系统会以进程为单位,分配系统资源,所以我们也说,进程是资源分配的最小单位。二、什么是线程线程存在与进程当中,是操作系统调度执行的最小单位。说通俗点,线程就是干活的。三、进程和线程的区别与联系如果说进程是一个资源管家,负责从主人那里要资源的话,那么线程就是干活的苦力。一个管家必须完成一项工作,就需要最少一个苦力,也就是说,一个进程最少包含一个线程,也可以包含多个线程。苦力要干活,就需要依托于管家,所以说一个线程,必须属于某一个进程。进程有自己的地址空间,线程使用进程的地址空间,也就是说,进程里的资源,线程都是有权访问的,比如说堆啊,栈啊,静态存储区什么的。线程就是个无产阶级,但无产阶级干活,总得有自己的劳动工具吧,这个劳动工具就是栈,线程有自己的栈,这个栈仍然是使用进程的地址空间,只是这块空间被线程标记为了栈。每个线程都会有自己私有的栈,这个栈是不可以被其他线程所访问的。四、一个牛叉的函数 - 创建进程和线程的基础Linux下进程和线程的创建都是通过clone实现的.clone函数功能强大,带了众多参数,clone可以让你有选择性的继承父进程的资源,你可以选择想vfork一样和父进程共享一个虚存空间,从而创造的是线程,你也可以不和父进程共享,你甚至可以选择创造出来的进程和父进程不再是父子关系,而是 兄弟关系。先有必要说下这个函数的结构int clone(int (*fn)(void *), void *child_stack, int flags, void *arg);这里fn是函数指针,我们知道进程的4要素,这个就是指向程序的指针, child_stack是为子进程分配系统堆栈空间(在linux下系统堆栈空间是2页面,就是8K的内存,其中在这块内存中,低地址上放入了值,这个值就是进程控制块task_struct的 值),flags就是标志用来描述你需要从父进程继承那些资源, arg就是传给子进程的参数)。下面是flags可以取的值标志 含义CLONE_PARENT 创建的子进程的父进程是调用者的父进程,新进程与创建它的进程成了兄弟而不是父子CLONE_FS 子进程与父进程共享相同的文件系统,包括root、当前目录、umaskCLONE_FILES 子进程与父进程共享相同的文件描述符(file descriptor)表CLONE_NEWNS 在新的namespace启动子进程,namespace描述了进程的文件hierarchyCLONE_SIGHAND 子进程与父进程共享相同的信号处理(signal handler)表CLONE_PTRACE 若父进程被trace,子进程也被traceCLONE_VFORK 父进程被挂起,直至子进程释放虚拟内存资源CLONE_VM 子进程与父进程运行于相同的内存空间CLONE_PID 子进程在创建时PID与父进程一致CLONE_THREAD Linux 2.4中增加以支持POSIX线程标准,子进程与父进程共享相同的线程群下面的例子是创建一个线程(子进程共享了父进程虚存空间,没有自己独立的虚存空间不能称其为进程)。父进程被挂起当子线程释放虚存资源后再继续执行。#include #include #include #define FIBER_STACK 8192int a;void * stack;int do_something() printf(This is son, the pid is:%d, the a is: %dn, getpid(), +a); free(stack); exit(1);int main() void * stack; a = 1; /为子进程申请系统堆栈 stack = malloc(FIBER_STACK); if(!stack) printf(The stack failedn); exit(0); printf(creating son thread!n); clone(&do_something, (char *)stack + FIBER_STACK, CLONE_VM|CLONE_VFORK, 0); printf(This is father, my pid is: %d, the a is: %dn, getpid(), a); exit(1);asmlinkage int sys_vfork(struct pt_regs regs) return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, s, 0);asmlinkage int sys_fork(struct pt_regs regs) return do_fork(SIGCHLD, regs.esp, s, 0);asmlinkage int sys_clone(struct pt_regs regs) unsigned long clone_flags; unsigned long newsp; clone_flags = regs.ebx; newsp = regs.ecx; if (!newsp) newsp = regs.esp; return do_fork(clone_flags, newsp, s, 0);关于fork, vfork,和clone的底层实现asmlinkage int sys_vfork(struct pt_regs regs) return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, s, 0);asmlinkage int sys_fork(struct pt_regs regs) return do_fork(SIGCHLD, regs.esp, s, 0);asmlinkage int sys_clone(struct pt_regs regs) unsigned long clone_flags; unsigned long newsp; clone_flags = regs.ebx; newsp = regs.ecx; if (!newsp) newsp = regs.esp; return do_fork(clone_flags, newsp, s, 0);这里可以看到它们都是对do_fork的调用,不过是参数不同而已.其中最重要的是 clone_flags参数, clone_flags由2部分组成,最低字节为信号类型,用于规定子进程去世时向父进程发出的信号。fork和vfork中这个信号就是SIGCHLD,而clone则可以由用户自己定义。高字节部分表示子进程从父进程继承哪些资源,fork的clone_flags参数的第2部分全部是0表示对所有资源都要复制给子进程。而vfork的参数是 (CLONE_VFORK | CLONE_VM), 表示子进程和父进程共享虚存内存CLONE_VFORK让父进程挂起, 直到子进程退出,至于clone则是由用户自己来定义的.五、pthread_create的实现pthread_create是基于clone实现的, 创建出来的其实是进程, 但这些进程与父进程共享很多东西,共享的东西都不用复制给子进程, 从而节省很多开销, 因此,这些子进程也叫轻量级进程(light-weight process)简称LWP. 每个LWP都会与一个内核线程绑定, 这样它就可以作为独立的调度实体参与cpu竞争. 如下图所示:LWP被pthread封装后, 以线程面目示人, 它有自己的id, 这里要区分phtread_create给LWP分配的id, 和操作系统给LWP分配的进程id. 这两者是不同的, 前者用于标志线程,可以暴露给用户, 后者其实就是进程的id, 它没有暴露出来, 必须通过系统调用来得到. 下面的例子演示了如何获取LWP的进程id 六、现出LWP的进程id#include #include #include #include #include #include #define N 5pid_t gettid() /直接使用224代替_NR_gettid也可以 return syscall(_NR_gettid);void *thread_func(void *arg) printf(thread started, pid = %dn, gettid(); while (1) sleep(1); int main(void) int i; pthread_t tidN; for (i = 0; i N; i+) pthread_create(&tidi, NULL, thread_func, NULL); sleep(1); for (i = 0; i N; i+) printf(tid = %lun, tidi); while (1) sleep(1); return 0;#include #include #include #include #include #include #define N 5pid_t gettid() /直接使用224代替_NR_gettid也可以 return syscall(_NR_gettid);void *thread_func(void *arg) printf(thread started, pid = %dn, gettid(); while (1) sleep(1); int main(void) int i; pthread_t tidN; for (i = 0; i N; i+) pthread_create(&tidi, NULL, thread_func, NULL); sleep(1); for (i = 0; i gcc lwp.c -o lwp -lpthreadwork ./lwpthreadstarted, pid =12248 threadstarted, pid =12249threadstarted, pid =12250 threadstarted, pid =12251 threadstarted, pid =12252 tid = 3078187888tid = 3069795184tid = 3061402480tid = 3053009776tid = 3044617072ps ax12247 pts/1 Sl+ 0:00 ./lwp12259 pts/3 R+ 0:00 ps axwork ps -Lf 12247UID PID PPID LWP C NLWP STIME TTY STAT TIME CMDkenby 12247 3758 12247 0 6 20:22 pts/1 Sl+ 0:00 ./lwpkenby 12247 3758 12248 0 6 20:22 pts/1 Sl+ 0:00 ./lwpkenby 12247 3758 12249 0 6 20:22 pts/1 Sl+ 0:00 ./lwpkenby 12247 3758 12250 0 6 20:22 pts/1 Sl+ 0:00 ./lwpkenby 12247 3758 12251 0 6 20:22 pts/1 Sl+ 0:00 ./lwpkenby 12247 3758 12252 0 6 20:22 pts/1 Sl+ 0:00 ./lwp此程序创建了5个线程, 但有6个LWP, 因为主线程也包含在里面, 主线程的线程id和进程id相同, 然后这6个线程的进程id都相同, 因为他们属于同一个进程.七、关于内核态和用户态核心态可以执行特权指令,但用户态只能执行非特权指令.这是如何实现的呢?Linux将内核程序和用户程序分开处理,分别运行在用户态和核心态。以32位x86架构为例,虚拟空间共4G,高地址的1G为系统程序运行的核心栈,低地址的3G空间为用户程序运行
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 咨询服务协议书样本
- 解析卷-北师大版8年级数学上册期中试题及参考答案详解(B卷)
- 2025版电子信息设备融资租赁委托合同样本
- 2025年度国内高端柴油批发与物流配送合作合同
- 2025版城镇化改造土方工程劳务分包合同范本
- 2025版住宅小区改造工程委托施工合同
- 2025版企业间融资租赁借款合同汇编
- 2025年度智能停车场设备安装与租赁合同样本
- 2025年度城市公共交通系统采购框架合同
- 2025年度典当借款与艺术品市场风险管理服务协议
- 普通高中生物学课程标准-(2024修订版)
- 项目质量保证措施及进度保证措施
- 打架斗殴安全教育
- 工程建设强制性条文-电力工程部分
- 档案数字化工作实施方案
- 苏教版四年级数学上册教案全册
- 短视频在互联网媒体与在线游戏行业的应用研究
- 中医体重管理
- 家长会校长讲座
- 中国脑小血管病诊治指南2023版
- 房地产中介服务操作手册
评论
0/150
提交评论