
被调用时,pcb由外存储器转内主存,pcb是存储器上的一组数据结构,需要的资源都分配在pcb上。
子进程(对应pid==0语句)调bai用pthread接口创建线程,在县城内将value赋值5,然后打印 CHILD: value=%d\n 此时duvalue = 5
父进程 (对应 pid >0 语句),等待子进程执行完成后(wait语句),打印PARENT: value=%d\n ,此时value =0。
扩展资料:
通过修改Linux系统内核参数ip_forward的方式实现路由功能,系统使用sysctl命令配置与显示在/proc/sys目录中的内核参数。首先在命令行输入:cat/proc/sys/net/ipv4/ip_forwad,检查Linux内核是不是开启IP转发功能。
如果结果为1,表明路由转发功能已经开启;如果结果为0,表明没有开启。出于安全考虑,Linux内核默认是禁止数据包路由转发的。在linux系统中,有临时和永久两种方法启用转发功能。
参考资料来源:百度百科-linux命令
进程是正在执行的一个程序或命令,每个进程都是一个运行的实体,都有自己的地址空间,并占用一定的系统资源。程序一旦运行就是进程。
进程可以看成程序执行的一个实例。进程是系统资源分配的独立实体,每个进程都拥有独立的地址空间。一个进程无法访问另一个进程的变量和数据结构,如果想让一个进程访问另一个进程的资源,需要使用进程间通信,比如管道,文件,套接字等。
Linux中进程分为以下三类:
①交互进程:由一个shell启动的进程,交互进程既可以在前台运行,也可以在后台运行。
②批处理进程:这种进程和终端没有联系,是一个进程序列。
③监控进程:也称守护进程,是一个在后台运行且不受任何终端控制的特殊进程,用于执行特定的系统任务。
进程的状态:
①可运行状态:此时进程正在运行或者正在运行队列中等待准备运行。
②等待状态:此时进程在等待一个事件的发生或某种系统资源。在Linux系统中等待状态又细分为两种等待状态:可中断的等待状态和不可中断的等待状态。
③暂停状态:处于暂停状态的进程被暂停运行。
④僵死状态:每个进程在运行结束后都会处于僵死状态,等待父进程调用进而释放系统资源,处于该状态的进程已经运行结束,但是它的父进程还没有释放其系统资源。
上回书说到 Linux进程的由来 和 Linux进程的创建 ,其实在同一时刻只能支持有限个进程或线程同时运行(这取决于CPU核数量,基本上一个进程对应一个CPU),在一个运行的 *** 作系统上可能运行着很多进程,如果运行的进程占据CPU的时间很长,就有可能导致其他进程饿死。为了解决这种问题, *** 作系统引入了 进程调度器 来进行进程的切换,轮流让各个进程使用CPU资源。
1)rq: 进程的运行队列( runqueue), 每个CPU对应一个 ,包含自旋锁(spinlock)、进程数量、用于公平调度的CFS信息结构、当前运行的进程描述符等。实际的进程队列用红黑树来维护(通过CFS信息结构来访问)。
2)cfs_rq: cfs调度的进程运行队列信息 ,包含红黑树的根结点、正在运行的进程指针、用于负载均衡的叶子队列等。
3)sched_entity: 把需要调度的东西抽象成调度实体 ,调度实体可以是进程、进程组、用户等。这里包含负载权重值、对应红黑树结点、 虚拟运行时vruntime 等。
4)sched_class:把 调度策略(算法)抽象成调度类 ,包含一组通用的调度 *** 作接口。接口和实现是分离,可以根据调度接口去实现不同的调度算法,使一个Linux调度程序可以有多个不同的调度策略。
1) 关闭内核抢占 ,初始化部分变量。获取当前CPU的ID号,并赋值给局部变量CPU, 使rq指向CPU对应的运行队列 。 标识当前CPU发生任务切换 ,通知RCU更新状态,如果当前CPU处于rcu_read_lock状态,当前进程将会放入rnp->blkd_tasks阻塞队列,并呈现在rnp->gp_tasks链表中。 关闭本地中断 ,获取所要保护的运行队列的自旋锁, 为查找可运行进程做准备 。
2) 检查prev的状态,更新运行队列 。如果不是可运行状态,而且在内核态没被抢占,应该从运行队列中 删除prev进程 。如果是非阻塞挂起信号,而且状态为TASK_INTER-RUPTIBLE,就把该进程的状态设置为TASK_RUNNING,并将它 插入到运行队列 。
3)task_on_rq_queued(prev) 将pre进程插入到运行队列的队尾。
4)pick_next_task 选取将要执行的next进程。
5)context_switch(rq, prev, next)进行 进程上下文切换 。
1) 该进程分配的CPU时间片用完。
2) 该进程主动放弃CPU(例如IO *** 作)。
3) 某一进程抢占CPU获得执行机会。
Linux并没有使用x86 CPU自带的任务切换机制,需要通过手工的方式实现了切换。
进程创建后在内核的数据结构为task_struct , 该结构中有掩码属性cpus_allowed,4个核的CPU可以有4位掩码,如果CPU开启超线程,有一个8位掩码,进程可以运行在掩码位设置为1的CPU上。
Linux内核API提供了两个系统调用 ,让用户可以修改和查看当前的掩码:
1) sched_setaffinity():用来修改位掩码。
2) sched_getaffinity():用来查看当前的位掩码。
在下次task被唤醒时,select_task_rq_fair根据cpu_allowed里的掩码来确定将其置于哪个CPU的运行队列,一个进程在某一时刻只能存在于一个CPU的运行队列里。
在Nginx中,使用了CPU亲和度来完成某些场景的工作:
worker_processes 4
worker_cpu_affinity 0001001001001000
上面这个配置说明了4个工作进程中的每一个和一个CPU核挂钩。如果这个内容写入Nginx的配置文件中,然后Nginx启动或者重新加载配置的时候,若worker_process是4,就会启用4个worker,然后把worker_cpu_affinity后面的4个值当作4个cpu affinity mask,分别调用ngx_setaffinity,然后就把4个worker进程分别绑定到CPU0~3上。
worker_processes 2
worker_cpu_affinity 01011010
上面这个配置则说明了两个工作进程中的每一个和2个核挂钩。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)