Linux下进程代码调试与理解
创建进程代码1:
#include <stdio.h>
void main( ) {
int p1,p2;
while((p1=fork())==-1); /*创建子进程p1*/
if (p1==0) putchar(‘b‘);
else {
while((p2=fork())==-1); /*创建子进程p2*/
if(p2==0) putchar(‘c‘);
else putchar(‘a‘);
}
}
调试结果:
分析:这里的if和else不是以前理解的选择分支。fork后产生的子进程和父进程并行运行的.这种理解是不正确的。if 和 else 还是选择分支。 主要的原因是,fork() 函数调用一次,返回两次。两次返回的区别是:子进程的返回值是0,父进程返回值为新子进程的进程ID,至于abc顺序为什么先后,偶也是懵的,只知道是随机的。
创建进程代码2:
#include <stdio.h>
void main( ) {
int p1,p2,i;
while((p1=fork())== -1); /*创建子进程p1*/
if (p1==0)
for(i=0; i<10; i++)
printf("daughter %d\n",i);
else {
while((p2=fork())== -1); /*创建子进程p2*/
if(p2==0)
for(i=0; i<10; i++)
printf("son %d\n",i);
else
for(i=0; i<10; i++)
printf("parent %d\n",i);
}
}
调试结果:
创建进程代码3(在2上加上sleep):
#include <stdio.h>
void main( ) {
int p1,p2,i;
while((p1=fork())== -1); /*创建子进程p1*/
if (p1==0)
for(i=0; i<10; i++) {
printf("daughter %d\n",i);
sleep(1);
}
else {
while((p2=fork())== -1); /*创建子进程p2*/
if(p2==0)
for(i=0; i<10; i++) {
printf("son %d\n",i);
sleep(1);
}
else
for(i=0; i<10; i++) {
printf("parent %d\n",i);
sleep(1);
}
}
}
调试结果:
创建进程代码4(在1上加上i观察结果):
#include <stdio.h>
void main( ) {
int p1,p2;
int i;
while((p1=fork())==-1); /*创建子进程p1*/
if (p1==0) putchar(‘b‘);
else {
while((p2=fork())==-1); /*创建子进程p2*/
if(p2==0) putchar(‘c‘);
else putchar(‘a‘);
}
i++;
printf("i=%d\n",i);
}
调试结果:
可以观察得出不同进程的i的值不同。
管理进程代码:
#include<stdio.h>
#include <stdlib.h>
#include<unistd.h>
void main( )
{
int pid;
pid=fork( ); /*创建子进程*/
switch(pid)
{
case -1: /*创建失败*/
printf("fork fail!\n");
exit(1);
case 0: /*子进程*/
execl("/bin/ls","ls","-1","-color",NULL);
printf("exec fail!\n");
exit(1);
default: /*父进程*/
wait(NULL); /*同步*/
printf("ls completed !\n");
exit(0);
}
}
调试结果:
如果缺少wait:
分析:少了个wait就会先是父进程执行completed后,子进程才把ls打印出来
如果目录写错:
分析:父进程未出现错误仍正常运行,子进程报错。
互斥程序代码(加锁):
#include <stdio.h>
#include <unistd.h>
void main() {
int p1,p2,i;
while((p1=fork( ))== -1); /*创建子进程p1*/
if (p1==0) {
lockf(1,1,0); /*加锁,这里第一个参数为stdout(标准输出设备的描述符)*/
for(i=0; i<10; i++)
printf("daughter %d\n",i);
lockf(1,0,0); /*解锁*/
} else {
while((p2=fork( ))==-1); /*创建子进程p2*/
if (p2==0) {
lockf(1,1,0); /*加锁*/
for(i=0; i<10; i++)
printf("son %d\n",i);
lockf(1,0,0); /*解锁*/
} else {
lockf(1,1,0); /*加锁*/
for(i=0; i<10; i++)
printf(" parent %d\n",i);
lockf(1,0,0); /*解锁*/
}
}
}
互斥程序调试结果:
分析:lockf(1,1,0)是锁定屏幕输出,不让其他进程可以输出到屏幕,lockf(1,0,0)则是解锁,所以拿到锁的那个进程能够在屏幕上一直输出。
互斥程序代码(未加锁):
#include <stdio.h>
#include <unistd.h>
void main() {
int p1,p2,i;
while((p1=fork( ))== -1); /*创建子进程p1*/
if (p1==0) {
//lockf(1,1,0); /*加锁,这里第一个参数为stdout(标准输出设备的描述符)*/
for(i=0; i<10; i++)
printf("daughter %d\n",i);
//lockf(1,0,0); /*解锁*/
} else {
while((p2=fork( ))==-1); /*创建子进程p2*/
if (p2==0) {
//lockf(1,1,0); /*加锁*/
for(i=0; i<10; i++)
printf("son %d\n",i);
//lockf(1,0,0); /*解锁*/
} else {
//lockf(1,1,0); /*加锁*/
for(i=0; i<10; i++)
printf(" parent %d\n",i);
//lockf(1,0,0); /*解锁*/c
}
}
}
运行结果:
分析:没有锁,他们是同步运行,顺序不分先后。
互斥程序代码(加锁+sleep):
#include <stdio.h>
#include <unistd.h>
void main() {
int p1,p2,i;
while((p1=fork( ))== -1); /*创建子进程p1*/
if (p1==0) {
lockf(1,1,0); /*加锁,这里第一个参数为stdout(标准输出设备的描述符)*/
for(i=0; i<10; i++){
printf("daughter %d\n",i);
sleep(1);
}
lockf(1,0,0); /*解锁*/
} else {
while((p2=fork( ))==-1); /*创建子进程p2*/
if (p2==0) {
lockf(1,1,0); /*加锁*/
for(i=0; i<10; i++){
printf("son %d\n",i);
sleep(1);
}
lockf(1,0,0); /*解锁*/
} else {
lockf(1,1,0); /*加锁*/
for(i=0; i<10; i++){
printf(" parent %d\n",i);
sleep(1);
}
printf(" parent %d\n",i);
lockf(1,0,0); /*解锁*/
}
}
}
运行结果:
分析:加上sleep也是一样的,他们是同步运行的。