exec1
代码如下:
1 #include <stdio.h> 2 #include <unistd.h> 3 int main(){ 4 char *arglist[3]; 5 arglist[0] = "ls"; 6 arglist[1] = "-l"; 7 arglist[2] = 0 ; 8 printf("* * * About to exec ls -l "); 9 execvp( arglist[0] , arglist ); 10 printf("* * * ls is done. bye "); 11 }
可以看到这个代码中用了execvp函数。
表头文件:
#include<unistd.h>
定义函数:
int execvp(const char file ,char const argv []);
execvp()会从PATH 环境变量所指的目录中查找符合参数file 的文件名,找到后便执行该文件,然后将第二个参数argv传给该欲执行的文件。
如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因存于errno中。
所以运行结果如下:
可以看到,exevp函数调用成功没有返回,所以没有打印出“* * * ls is done. bye”这句话。
exec2
1 #include <stdio.h> 2 #include <unistd.h> 3 4 int main() 5 { 6 char *arglist[3]; 7 char*myenv[3]; 8 myenv[0] = "PATH=:/bin:"; 9 myenv[1] = NULL; 10 11 arglist[0] = "ls"; 12 arglist[1] = "-l"; 13 arglist[2] = 0 ; 14 printf("* * * About to exec ls -l "); 15 16 execlp("ls", "ls", "-l", NULL); 17 printf("* * * ls is done. bye ");
它与exec1的区别就在于exevp函数的第一个参数,exec1传的是ls,exec2直接用的arglist[0],不过由定义可得这两个等价,所以运行结果是相同的。
exec3
代码如下:
1 #include <stdio.h> 2 #include <unistd.h> 3 4 int main() 5 { 6 char *arglist[3]; 7 char*myenv[3]; 8 myenv[0] = "PATH=:/bin:"; 9 myenv[1] = NULL; 10 11 arglist[0] = "ls"; 12 arglist[1] = "-l"; 13 arglist[2] = 0 ; 14 printf("* * * About to exec ls -l "); 15 16 execlp("ls", "ls", "-l", NULL); 17 printf("* * * ls is done. bye "); 18 }
这个代码里使用了execlp函数,用法如下:
头文件:
#include<unistd.h>
定义函数:
int execlp(const char * file,const char * arg,....);
函数说明:
execlp()会从PATH 环境变量所指的目录中查找符合参数file的文件名,找到后便执行该文件,然后将第二个以后的参数当做该文件的argv[0]、argv[1]……,最后一个参数必须用空指针(NULL)作结束。如果用常数0来表示一个空指针,则必须将它强制转换为一个字符指针,否则将它解释为整形参数,如果一个整形数的长度与char * 的长度不同,那么exec函数的实际参数就将出错。如果函数调用成功,进程自己的执行代码就会变成加载程序的代码,execlp()后边的代码也就不会执行了.
返回值:
如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因存于errno 中。
也就是说,这个代码指定了环境变量,然后依然执行了ls -l指令,成功后没有返回,所以最后一句话不会输出。运行结果同exec1.
forkdemo1
代码如下:
1 #include <stdio.h> 2 #include<sys/types.h> 3 #include<unistd.h> 4 int main() 5 { 6 int ret_from_fork, mypid; 7 mypid = getpid(); 8 printf("Before: my pid is %d ", mypid); 9 ret_from_fork = fork(); 10 sleep(1); 11 printf("After: my pid is %d, fork() said %d ", 12 getpid(), ret_from_fork); 13 14 return 0; 15 }
代码解释:
这个代码先是打印进程pid,然后调用fork函数生成子进程,休眠一秒后再次打印进程id,这时父进程打印子进程pid,子进程返回0.
运行结果如下:
forkdemo2
代码如下:
1 #include <stdio.h> 2 #include <unistd.h> 3 4 int main() 5 { 6 printf("before:my pid is %d ", getpid() ); 7 fork(); 8 fork(); 9 printf("aftre:my pid is %d ", getpid() ); 10 11 return 0; 12 }
这个代码调用两次fork,一共产生四个子进程,所以会打印四个aftre输出。
结果如图:
forkdemo3
代码如下:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 5 int main() 6 { 7 int fork_rv; 8 9 printf("Before: my pid is %d ", getpid()); 10 11 fork_rv = fork(); /* create new process */ 12 13 if ( fork_rv == -1 ) /* check for error */ 14 perror("fork"); 15 else if ( fork_rv == 0 ){ 16 printf("I am the child. my pid=%d ", getpid()); 17 18 exit(0); 19 } 20 else{ 21 printf("I am the parent. my child is %d ", fork_rv); 22 exit(0); 23 } 24 25 return 0; 26 }
fork产生子进程,父进程返回子进程pid,不为0,所以输出父进程的那句话,子进程返回0,所以会输出子进程那句话。
结果如下:
forkdemo4
代码:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 5 int main() 6 { 7 int fork_rv; 8 9 printf("Before: my pid is %d ", getpid()); 10 11 fork_rv = fork(); /* create new process */ 12 13 if ( fork_rv == -1 ) /* check for error */ 14 perror("fork"); 15 16 else if ( fork_rv == 0 ){ 17 printf("I am the child. my pid=%d ", getpid()); 18 printf("parent pid= %d, my pid=%d ", getppid(), getpid()); 19 exit(0); 20 } 21 22 else{ 23 printf("I am the parent. my child is %d ", fork_rv); 24 sleep(10); 25 exit(0); 26 } 27 28 return 0; 29 }
先打印进程pid,然后fork创建子进程,父进程返回子进程pid,所以输出parent一句,休眠十秒;子进程返回0,所以输出child与之后一句。
运行结果如下:
forkgdb
代码如下:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 5 int gi=0; 6 int main() 7 { 8 int li=0; 9 static int si=0; 10 int i=0; 11 12 pid_t pid = fork(); 13 if(pid == -1){ 14 exit(-1); 15 } 16 else if(pid == 0){ 17 for(i=0; i<5; i++){ 18 printf("child li:%d ", li++); 19 sleep(1); 20 printf("child gi:%d ", gi++); 21 printf("child si:%d ", si++); 22 } 23 exit(0); 24 25 } 26 else{ 27 for(i=0; i<5; i++){ 28 printf("parent li:%d ", li++); 29 printf("parent gi:%d ", gi++); 30 sleep(1); 31 printf("parent si:%d ", si++); 32 } 33 exit(0); 34 35 } 36 return 0; 37 }
显示结果如下:
这个的主要区别是在,父进程打印是先打印两句,然后休眠一秒,然后打印一句,子进程先打印一句,然后休眠一秒,然后打印两句。并且这两个线程是并发的,所以可以看到在一个线程休眠的那一秒,另一个线程在执行,并且线程之间相互独立互不干扰。
psh1
代码:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <unistd.h> 5 6 #define MAXARGS 20 7 #define ARGLEN 100 8 9 int execute( char *arglist[] ) 10 { 11 execvp(arglist[0], arglist); 12 perror("execvp failed"); 13 exit(1); 14 } 15 16 char * makestring( char *buf ) 17 { 18 char *cp; 19 20 buf[strlen(buf)-1] = '