2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > linuxC语言编程

linuxC语言编程

时间:2019-05-25 19:53:46

相关推荐

linuxC语言编程

实验4

1、fork与vfork

fork

#include<sys/types.h>#include<unistd.h>#include<stdio.h>int main(){pid_t pid;pid = fork();if(pid<0)printf("error in fork!\n");else if(pid == 0)printf("I am the child process,ID is %d\n",getpid())else printf("I am the parent process,ID is %d\n",getpid();return 0;}

fork创建出来的进程,父子进程没有必须的执行顺序,顺序也不是确定的,这取决于linux内核的调度算法。

fork在使用时会拷贝父进程的数据段和代码段,这就避免了在操作子进程数据时导致父进程数据发生改变。

vfork

#include<sys/types.h>#include<unistd.h>#include<stdio.h>int main(){pid_t pid;pid = vfork();if(pid<0)printf("error in fork!\n");else if(pid == 0){printf("I am the child process,ID is %d\n",getpd());exit(0);}else printf("I am the parent process,ID is %d\n",getpid();return 0;}

vfork则是先执行子进程,且在子进程执行结束收回后,才能执行父进程的内容。

由于vfork是共享父进程的数据段,所以使用vfork时需格外注意子进程的回收情况,如果没有回收就会出现段错误。

区别:

执行顺序是否共用数据段和代码段

对比分析

#include <stdio.h> #include <unistd.h> #include <sys/types.h>#include <stdlib.h>int main(void){int data = 0 ; pid_t pid ; int choose = 0 ; while((choose = getchar( ))!='q'){switch(choose){case '1': pid = fork( ); if(pid < 0 ) {printf("Error !\n"); } if(pid == 0 ){data++; exit(0); } wait(pid);//wait用于回收子进程if(pid > 0 ){printf("data is %d\n",data); }break; case '2' :pid = vfork( ); if(pid < 0 ){perror("Error !\n"); } if(pid == 0 ){data++;exit(0); } wait(pid); if(pid > 0 ){printf("data is %d\n",data); } break; default : break; } } }

代码分析:

每当输入1的时候就会用fork创建子进程;每当输入2的时候就会用vfork创建子进程;子进程执行data++命令,父进程打印data值。

结果:

每次输入1的时候,并没有经过data++指令就将data的值打印了出来;每次输入2的时候,会先进行data++指定再打印data的值。当多次重复输入1后,会发现data的值依旧是初始值;在多次重复输入2后,data的值都会加一。

结果分析:

结果一:

输入1,使用fork创建子进程。由于 fork创建的子进程,其子进程和父进程的执行顺序是不确定的,每次都是先执行了父进程,所以打印结果就没有经过data++这一步。

如果凑巧先执行了子进程,那么打印的结果就是data++。这个可以用sleep或wait函数去控制先执行子进程然后观察结果。

输入2,使用vfork创建子进程。vfork创建出的子进程,父进程会等子进程执行完且回收了子进程资源后再开始执行,所以每次都打印出的是data++。

结果二:

使用fork创建子进程时,fork会拷贝父进程的数据段和代码段。子进程在执行指令的时候也是在拷贝下来的数据段和代码段上执行,并不会影响到父进程的数据段内容,所以每一次data++都是在取父进程中的data值,且data值改变后不会影响到父进程中的data值。使用vfork创建子进程时,vfork是共享父进程的数据段。子进程执行data++也就改变了父进程中的data值。

2、完善程序

要求:

实现一个程序启动另一个程序后自身仍然在运行,即在子进程中加载执行其他程序而父进程等待子进程结束后才结束。

参考

#include <error.h> #include <stdio.h> #include <unistd.h> #include <sys/types.h> int main(){/*接受键盘输入命令字符*//*创建子进程*/if(创建失败) /*打印“创建子进程失败”*/else if (子进程){/*用exec()加载程序执行输入的命令*/}else {/*等待子进程信息*//*继续父进程的执行*/}}

#include <error.h> #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <wait.h>int main(){char a[20]={0};pid_t pid;/*接受键盘输入命令字符*/printf("请输入程序名(命令路径):");scanf("%s",a);/*创建子进程*/pid=fork();if(pid<0) /*打印“创建子进程失败”*/{printf("Error:fork fail!\n");}else if(pid==0){/*用exec()加载程序执行输入的命令*/execv(a,0);_exit(0);}else{/*等待子进程信息*/wait(NULL);/*继续父进程的执行*/printf("This is parent process\n");}}

3、父子进程通过无名管道传递三条消息

程序思路:

父进程发送信息,三条信息分三次发送;子进程也是一条信息一条信息的获取。父进程向管道写入一条信息后sleep1秒,然后等子进程读取出来,读完之后也sleep1秒如此往复。完成三条信息的传输。

#include <stdio.h>#include <sys/wait.h>#include <sys/types.h>#include <unistd.h>#include <string.h>#include <stdlib.h>int main(){pid_t pid;char buf[3][35]={0};int fd[2]={0};int i;char* context[]={"管道文件的测试程序开始","管道文件测试正在进行","管道通信测试结束"};switch(pipe(fd)){case -1:printf("ERROR:Creat pipe fail!\n");exit(1);break;case 0:switch(pid=fork()){case -1:printf("ERROR:Creat pipe fail!\n");exit(1);case 0:close(fd[1]);for(i=0;i<3;i++){read(fd[0],buf[i],35);printf("%s\n",buf[i]);sleep(1);}break;default :close(fd[0]);for(i=0;i<3;i++){write(fd[1],context[i],strlen(context[i]));sleep(1);}wait(NULL);break;}break;}}

4、 利用Linux/UNIX的软中断信号,编写一段C语言程序完成:显示数字1到100,在程序运行中如果捕获到一个SIGINT信号,则转去执行一段显示当前系统时间的程序。在编程中要考虑到信号被复位的情况,使程序能够实现多次被打断却多次的恢复执行。

#include <signal.h>#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <time.h>#include <stdlib.h>void main(){void catchint(int signo);int i;signal(SIGINT,catchint);for(i=1;i<101;i++){printf("%d\n",i);sleep(1);}printf("Exiting.\n");exit(0);}void catchint(int signo){struct tm *prt;time_t it;it=time(NULL);prt=localtime(&it);printf("%4d年%02d月%02d日 %2d:%2d:%d\n",prt->tm_year+1900,prt->tm_mon+1,prt->tm_mday,prt->tm_hour,prt->tm_min,prt->tm_sec);}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。