forklinux等
❶ linux应用程序中出现两次fork的解释
一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程。
在一些程序中经常看见使用两次fork创建子进程,原因如下:
以下摘自《UNIX环境高级编程》
如果一个进程fork一个子进程,但不要它等待子进程终止,也不希望子进程处于僵死状态直到父进程终止,实现这一要求的技巧是调用fork两次。程序如下:
#include
"apue.h"
#include
<sys/wait.h>
int
main(void)
{
❷ linux中的fork函数到底做了什么事
额........每启动一个进程并不一定要执行fork.fork只是系统最后封装的一个系统调用.你在程序里不使用fork的话.使用其它方式启动进程.就不是fork.fork族里有很多函数...............exec也可替换当前进程......系统内核里生成一个进程用的是clone这个函数.
就比如要盖个房子.一个人干,要先挖土再调水泥再摆砖头再盖墙这样一步一步做.但是如果有多个人.就是可以多个人同时做这些事,一个挖土,一个调水泥.一个摆砖头.这样就省了很多时间.进程也是如此.fork的作用就是创建新进程.
这么多人一起盖房子,总不能各自盖各自的,需要大家协调来做.不能土没挖好就摆砖,没放砖就抹水泥一样.这个时候需要一个工头来管理大家.工头通过每个人的名字来指挥每个人干活.进程就通过pid来指挥一个进程干活.工人需要知道自己的工头是谁,好向他报告碰到的情况.进程需要知道自己的父进程是谁报告自己的情况.
这样就明白fork为何要返回进程的id了吧?fork是不会返回父进程的id的.
工头找了一个新工人干活.从工头知道这个新工人的名字时刻开始,新工人就会投入这个团队一起干活了.fork返回pid的时候就表示这个进程在这个进程团队里了.工头可以直接告诉工人要干什么而不会让其他工人误以为这是自己的活.但是程序并没有这么智能.这个时候就需要有一个状态(if(!pid){....这是工人干的活...})表明这个工人的代码从什么位置开始,到什么位置结束.
❸ linux fork 会共享哪些东西
fork()不仅创建出与父进程代码相同的子进程,而且父进程在fork执行点的所有上下文场景也被自动复制到子进程中,包括:
—全局和局部变量
—打开的文件句柄
—共享内存、消息等同步对象
由于pipe调用相当于创建了2个文件句柄,因此在fork后这两个句柄也被自动复制到子进程中,对这两个句柄的操作效果与在主进程中的操作效果是一致的,这就使父子进程之间很容易通过该机制实现数据交换,如:
假设pipe产生的句柄为P[0],P[1],在fork后父子进程都拥有了P[0],P[1]句柄,那么:
—父进程可向自己的P[1]中写入数据,子进程从P[0]中即可读出该数据;切记此时父进程不能也从P[0]读数据,否则自己写入的数据可能先被自己读走了
—反之亦然,子进程向P[1]中写入数据后,父进程从P[0]中可读出该数据;切记此时子进程不要从P[0]读走数据
你可能难以理解为什么进程内部的数据读写会被传递到另一个进程,但别忘了,pipe匿名管道和文件,socket等一样是属于操作系统的管理对象,对其进行读写都是由OS的内核代码来进行控制的。在父进程调用pipe创建出管道后,该管道对象是存储在OS内部的,父进程得到的P[0]和P[1]都只是对该对象的引用(相当于指针);在fork出子进程后,子进程复制出的也只是同一个指针,所指向的还是OS中的同一个对象,这就是为什么父子进程能通过其进行互相通信的原因。
❹ linux下的fork函数
不止三个,子进程仍然在循环体内,所以子进程也会根据它的i值来做循环,然后fork子进程的子进程,但是你的程序也有问题,父进程打印后没有等待子进程运行结束就return了,这样有些子进程还来不仅运行就退出了。所以你的程序的输出结果是不可靠的,也是可能是随机的(其结果会根据运行时操作系统的具体调度的不同而不同)。所以我给你改了一下,这样就能让所有被fork的子进程(包括这些子进程再次fork出来的子进程)都有机会运行。
int main()
{
int i;
int my_pid;
int chld_pid;
for( i= 0; i< 3; i++)
{
chld_pid= fork();
if(chld_pid== 0) {
my_pid = getpid();
printf("i = %d, child pid %d\n", i, my_pid);
}
else {
my_pid = getpid();
printf("i = %d, parent pid %d, child pid %d\n",i, my_pid, chld_pid);
wait(0); /*waiting for the completion of child */
}
}
return 0;
}
运行后的结果为:
i = 0, parent pid 5294, child pid 5295
i = 0, child pid 5295
i = 1, parent pid 5295, child pid 5296
i = 1, child pid 5296
i = 2, parent pid 5296, child pid 5297
i = 2, child pid 5297
i = 2, parent pid 5295, child pid 5298
i = 2, child pid 5298
i = 1, parent pid 5294, child pid 5299
i = 1, child pid 5299
i = 2, parent pid 5299, child pid 5300
i = 2, child pid 5300
i = 2, parent pid 5294, child pid 5301
i = 2, child pid 5301
这样你就可以看到,实际上有7个子进程被fork出来,其中有3个是被真正的父进程(5294)fork出来的,而其余的则是被5294的子进程(甚至子进程的子进程)所fork出来的。其中的逻辑关系从打印出来的进程号就可以一目了然了,我就不赘述了。
❺ linux中fork,source和exec的区别
exec和source都属于bash内部命令(builtins commands),在bash下输入man exec或man source可以查看所有的内部命令信息。
bash shell的命令分为两类:外部命令和内部命令。外部命令是通过系统调用或独立的程序实现的,如sed、awk等等。内部命令是由特殊的文件格式(.def)所实现,如cd、history、exec等等。
在说明exec和source的区别之前,先说明一下fork的概念。
fork是linux的系统调用,用来创建子进程(child process)。子进程是父进程(parent process)的一个副本,从父进程那里获得一定的资源分配以及继承父进程的环境。子进程与父进程唯一不同的地方在于pid(process id)。
环境变量(传给子进程的变量,遗传性是本地变量和环境变量的根本区别)只能单向从父进程传给子进程袭腊。不管子进程的环境变量如何变化,都不会影响父进程的环境变量。
shell script:
有两种方法执行shell scripts,一种是新产生一个shell,然后执行相应的shell scripts;一种是在当前shell下执行,不再启用其他shell。
新产生一个shell然后再执行scripts的方法是在scripts文件开头加入以下语句
#!/bin/sh
一般的script文件(.sh)即是这种用法。这种方法先启用新的sub-shell(新的子进程),然后在其下执行命令。
另外一种方法就是上面说过的source命令,不再产生新的shell,而在当前shell下执行一切命令。
source:
source命令即点(.)命令。
在bash下输入man source,找到source命拍没滑令解释处,可以看到解释"Read and execute commands from filename in the current shell environment and ..."。从中可以知道,source命令是在当前进程中执行参数文件中的各个命令,而不是察银另起子进程(或sub-shell)。source filename or .filename 执行filename中的命令。
exec:
在bash下输入man exec,找到exec命令解释处,可以看到有"No new process is created."这样的解释,这就是说exec命令不产生新的子进程。那么exec与source的区别是什么呢?
exec命令在执行时会把当前的shell process关闭,然后换到后面的命令继续执行。
======================================================================================================================
下面我们写个脚本来测试一下,这样你就会很容易的读懂我上面所说的东西~
1.sh
#!/bin/bashA=Becho"PIDfor1.shbeforeexec/source/fork:
"exportAecho"1.sh:$Ais$A"case$1inexec)echo"usingexec..."exec./2.sh;;source)echo"usingsource..."../2.sh;;∗)echo"usingforkbydefault..."./2.sh;;esacecho"PIDfor1.shafterexec/source/fork:
"echo"1.sh:$Ais$A"
2.sh
#!/bin/bash
echo"PIDfor2.sh:$$"
echo"2.shget$A=$Afrom1.sh"
A=C
exportA
echo"2.sh:$Ais$A"
=================》》》》》》》》》》》
测试结果:
[root@node2 ~]$ ./1.sh fork
PID for 1.sh before exec/source/fork:10175
1.sh: $A is B
using fork by default...
PID for 2.sh:10176
2.sh get $A=B from 1.sh
2.sh: $A is C
PID for 1.sh after exec/source/fork:10175
1.sh: $A is B
=============================================
[root@node2 ~]$ ./1.sh source
PID for 1.sh before exec/source/fork:10185
1.sh: $A is B
using source...
PID for 2.sh:10185
2.sh get $A=B from 1.sh
2.sh: $A is C
PID for 1.sh after exec/source/fork:10185
1.sh: $A is C
=============================================
[root@node2 ~]$ ./1.sh exec
PID for 1.sh before exec/source/fork:10194
1.sh: $A is B
using exec...
PID for 2.sh:10194
2.sh get $A=B from 1.sh
2.sh: $A is C
[cpsuser@cps-svr-153 zy]$
=============================================
从以上结果可以看出:
1.执行source和exec的过程中没有产生新的进程,而fork是默认的运行方式,在运行的过程中会产生新的进程,也就是子进程
2.source和exec的区别在于exec执行完毕后没有输出进程,也就是说运行完毕2.sh后直接退出了,没有返回1.sh
3.fork和source的最后一句输出分别为:1.sh: $A is B (fork,说明它运行的环境不一样,要不然输出的应该是C)
1.sh: $A is C(source,说明从始至终都是在一个shell中执行)
小节:
source 指定脚本中的命令在同一个shell中运行。(默认shell中的命令都是创建sub-shell,然后执行。执行完后,返回父shell)
fork 就是创建sub-shell运行脚本中的命令,和默认运行方式相同。
exec 和source相似,区别就是,运行完毕命令后退出,不会返回父shell
❻ linux下的fork()运用
fork()创建一个子进程,fork()进入内核,调用一次返回两次,如果返回的pid == 0子进程先返回,如果pid > 0(此时返回的是子进程的pid),父进程先返回。至于子进程和父进程哪个先返回,要看内核的调度算法。输出次序乱序,都有可能。父进程和子进程是并发执行的。
❼ 关于Linux的fork()
= OR ==
你初学者吧,请把赋值 =
和 == 值比较 搞清楚啊
= value assignment
== value compare