第十二周(11.23-11.29):
一、学习目标
掌握进程控制掌握信号处理的方法掌握管道和fifo进行进程间通信的方法
二、学习资源
编译、运行、阅读、理解process.tar.gz压缩包中的代码
三、学习任务
(提示:请将要求学生完成的任务、测验或思考题列在此处)编译、运行、阅读、理解process.tar.gz压缩包中的代码
一些头文件的用处:
stdio.h 标准输入输出stdlib.h C标准函数库unistd.h Unix类系统定义符号常量
exec1
#include#include int main(){char *arglist[3];arglist[0] = "ls";arglist[1] = "-l";arglist[2] = 0 ;//NULLprintf("* * * About to exec ls -l\n");//不成功调用exevp,返回-1execvp( "ls" , arglist );printf("* * * ls is done. bye");return 0;}
- 没打印出“* * * ls is done. bye”这句话
exec2
#include#include int main(){char *arglist[3];arglist[0] = "ls";arglist[1] = "-l";arglist[2] = 0 ;printf("* * * About to exec ls -l\n");execvp( arglist[0] , arglist );printf("* * * ls is done. bye\n");}
- 运行结果同1
exec3
#include#include int main(){char *arglist[3];char *myenv[3];myenv[0] = "PATH=:/bin:";myenv[1] = NULL;arglist[0] = "ls";arglist[1] = "-l";arglist[2] = 0 ;printf("* * * About to exec ls -l\n");execlp("ls", "ls", "-l", NULL);printf("* * * ls is done. bye\n");}
- 运行结果同1
forkdemo1
#include#include #include int main(){int ret_from_fork, mypid;mypid = getpid(); printf("Before: my pid is %d\n", mypid);//打印PIDret_from_fork = fork();//一次调用forksleep(1);//休息一秒printf("After: my pid is %d, fork() said %d\n", getpid(), ret_from_fork);//父进程打印子进程PIDreturn 0;}
forkdemo2
#include#include int main(){printf("before:my pid is %d\n", getpid() );fork();//第一次调用forkfork();//第二次调用forkprintf("aftre:my pid is %d\n", getpid() );//输出四次aftrereturn 0;}
foekdemo3
#include#include #include int main(){int fork_rv;printf("Before: my pid is %d\n", getpid());fork_rv = fork(); /* create new process */if ( fork_rv == -1 ) /* check for error */ perror("fork");else if ( fork_rv == 0 ){ printf("I am the child. my pid=%d\n", getpid()); exit(0);}else{ printf("I am the parent. my child is %d\n", fork_rv); exit(0);}return 0;}
- 先输出父亲进程PID
- 表面身份并输出子进程PID
forkdemo4
#include#include #include int main(){int fork_rv;printf("Before: my pid is %d\n", getpid());fork_rv = fork(); /* create new process */if ( fork_rv == -1 ) /* check for error */ perror("fork");else if ( fork_rv == 0 ){ printf("I am the child. my pid=%d\n", getpid()); printf("parent pid= %d, my pid=%d\n", getppid(), getpid()); exit(0);}else{ printf("I am the parent. my child is %d\n", fork_rv); sleep(10); exit(0);}return 0;}
- 输出父亲进程PID
- 表明身份,输出PID
- 总结父进程和子进程PID
forkgdb
#include#include #include int gi=0;int main(){int li=0;static int si=0;int i=0;pid_t pid = fork();if(pid == -1){ exit(-1);}else if(pid == 0){ for(i=0; i<5; i++){ printf("child li:%d\n", li++); sleep(1); printf("child gi:%d\n", gi++); printf("child si:%d\n", si++); } exit(0); }else{ for(i=0; i<5; i++){ printf("parent li:%d\n", li++); printf("parent gi:%d\n", gi++); sleep(1); printf("parent si:%d\n", si++); }exit(0); }return 0;}
- 该程序是并发执行的
- 当一个程序执行时,另一个程序在休眠交替
psh1
#include#include #include #include #define MAXARGS 20 #define ARGLEN 100 int execute( char *arglist[] ){execvp(arglist[0], arglist); perror("execvp failed");exit(1);}char * makestring( char *buf ){char *cp;buf[strlen(buf)-1] = '\0'; cp = malloc( strlen(buf)+1 ); if ( cp == NULL ){ fprintf(stderr,"no memory\n"); exit(1);}strcpy(cp, buf); return cp; }int main(){char *arglist[MAXARGS+1]; int numargs; char argbuf[ARGLEN]; numargs = 0;while ( numargs < MAXARGS ){ printf("Arg[%d]? ", numargs); if ( fgets(argbuf, ARGLEN, stdin) && *argbuf != '\n' ) arglist[numargs++] = makestring(argbuf); else { if ( numargs > 0 ){ arglist[numargs]=NULL; execute( arglist ); numargs = 0; } }}return 0;}
- 手动输入指令,回车表示结束
push2
- 同push1,多了循环
testbuf1
#include#include int main(){printf("hello");fflush(stdout);while(1);}
- 输出:
testbuf2
#includeint main(){printf("hello\n");while(1);}
- 输出同testbuf1
testbuf3
#includeint main(){fprintf(stdout, "1234", 5);fprintf(stderr, "abcd", 4);}
- 输出:
testpid
#include#include #include int main(){printf("my pid: %d \n", getpid());//输出进程PIDprintf("my parent's pid: %d \n", getppid());//输出父亲进程PIDreturn 0;}
- 输出见代码分析
testpp
#include#include int main(){char **pp;pp[0] = malloc(20);return 0;}
- 输出
testsystem
#includeint main ( int argc, char *argv[] ){system(argv[1]);system(argv[2]);return EXIT_SUCCESS;} /* ---------- end of function main ---------- */
waitdemo
#include#include #include #include #include #define DELAY 4void child_code(int delay){printf("child %d here. will sleep for %d seconds\n", getpid(), delay);sleep(delay);printf("child done. about to exit\n");exit(17);}void parent_code(int childpid){int wait_rv=0; /* return value from wait() */wait_rv = wait(NULL);printf("done waiting for %d. Wait returned: %d\n", childpid, wait_rv);}int main(){int newpid;printf("before: mypid is %d\n", getpid());if ( (newpid = fork()) == -1 ) perror("fork");else if ( newpid == 0 ) child_code(DELAY);else parent_code(newpid);return 0;}
- 输出当前进程
当子进程存在,则终止子进程,输出子进程PID
waitdemo2
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #define DELAY 10 void child_code(int delay) { printf("child %d here. will sleep for %d seconds\n", getpid(), delay); sleep(delay); printf("child done. about to exit\n"); exit(27); } void parent_code(int childpid) { int wait_rv; int child_status; int high_8, low_7, bit_7; wait_rv = wait(&child_status); printf("done waiting for %d. Wait returned: %d\n", childpid, wait_rv); high_8 = child_status >> 8; /* 1111 1111 0000 0000 / low_7 = child_status & 0x7F; / 0000 0000 0111 1111 / bit_7 = child_status & 0x80; / 0000 0000 1000 0000 */ printf("status: exit=%d, sig=%d, core=%d\n", high_8, low_7, bit_7); } int main() { int newpid; printf("before: mypid is %d\n", getpid()); if ( (newpid = fork()) == -1 ) perror("fork"); else if ( newpid == 0 ) child_code(DELAY); else parent_code(newpid); }输出结果同1
environvar
#includeint main(void){extern char **environ;int i;for(i = 0; environ[i] != NULL; i++) printf("%s\n", environ[i]);return 0;}
- 输出所用的所有的详细信息