进程控制
- 进程等待
- 进程程序替换
进程等待
如果子进程没有退出
而父进程在进行执行waitpid进行等待,阻塞等待, 进程阻塞了
在等待某种条件发生(子进程退出)
进程程序替换
1 #include <stdio.h>2 #include <unistd.h>3 4 int main()5 {6 printf("testexec ... begin\n");7 8 execl("/usr/bin/ls", "ls", "-l", "-a", NULL); 9 10 printf("testexec ... end!\n");11 return 0;12 }
[tt@kunkun testexec]$ ./testexec
testexec ... begin
total 28
drwxrwxr-x 2 tt tt 4096 Feb 18 20:56 .
drwxrwxr-x 6 tt tt 4096 Feb 18 20:25 ..
-rw-rw-r-- 1 tt tt 70 Feb 18 20:29 Makefile
-rwxrwxr-x 1 tt tt 8408 Feb 18 20:56 testexec
-rw-rw-r-- 1 tt tt 192 Feb 18 20:56 testexec.c
exec*系列的函数,执行完毕之后,后续的代码不见了,因为被替换了
exec函数的返回值可以不关心了。只要替换成功,就不会向后继续运行,只要继续运行了,一定是替换失败了
多进程版
fork创建子进程,让子进程自己去替换 wait
int execl(const char *path, const char *arg, ...);
1 #include <stdio.h>2 #include <unistd.h>3 #include <stdlib.h>4 #include <sys/types.h>5 #include <sys/wait.h>6 7 int main()8 {9 printf("testexec ... begin\n");10 11 pid_t id = fork();12 if(id == 0)13 {14 //child15 execl("/usr/bin/ls", "ls", "-l", "-a", NULL);16 exit(1);17 }18 19 //father20 int status = 0;21 pid_t rid = waitpid(id, &status, 0); 22 if(rid > 0)23 {24 printf("father wait sucess, child exit code: %d\n", WEXITSTATUS(status));25 }26 27 printf("testexec ... end!\n");28 return 0;29 }
[tt@kunkun testexec]$ ./testexec
testexec ... begin
total 28
drwxrwxr-x 2 tt tt 4096 Feb 18 21:51 .
drwxrwxr-x 6 tt tt 4096 Feb 18 20:25 ..
-rw-rw-r-- 1 tt tt 70 Feb 18 20:29 Makefile
-rwxrwxr-x 1 tt tt 8616 Feb 18 21:51 testexec
-rw-rw-r-- 1 tt tt 530 Feb 18 21:51 testexec.c
father wait sucess, child exit code: 0
testexec ... end!
int execv(const char *path, char *const argv[]);
1 #include <stdio.h>2 #include <unistd.h>3 #include <stdlib.h>4 #include <sys/types.h>5 #include <sys/wait.h>6 7 int main()8 {9 printf("testexec ... begin\n");10 11 pid_t id = fork();12 if(id == 0)13 {14 sleep(2);15 char *const argv[] =16 {17 (char*)"ls",18 (char*)"-l",19 (char*)"-a",20 (char*)"--color",21 NULL22 };23 //child24 execv("/usr/bin/ls", argv);25 exit(1);26 } 27 28 //father29 int status = 0;30 pid_t rid = waitpid(id, &status, 0);31 if(rid > 0)32 {33 printf("father wait sucess, child exit code: %d\n", WEXITSTATUS(status));34 }35 36 printf("testexec ... end!\n");37 return 0;38 }
int execvp(const char *file, char *const argv[]);
用户可以不传要执行的文件的路径(但是文件名要传),直接告诉exec* ,我要执行谁就行
p:查找这个程序,系统会在环境变量PATH中进行查找
int execvpe(const char *file, char *const argv[], char *const envp[]);
第三个参数整体替换所有环境变量
1、用全新的给子进程
2、用老的环境变量给子进程,environ
3、老的环境变量稍微修改,给子进程
Makefile
1 .PHONY:all2 all:testexec mypragma3 4 testexec:testexec.c5 gcc -o $@ $^ 6 mypragma:mypragma.cc7 g++ -o $@ $^ -std=c++118 .PHONY:clean9 clean:10 rm -f testexec mypragma
1 #include <iostream> 2 #include <unistd.h> 3 4 using namespace std; 5 6 int main() 7 { 8 cout << "hello C++, I am a C++ pragma!" << getpid() << endl; 9 cout << "hello C++, I am a C++ pragma!" << getpid() << endl; 10 cout << "hello C++, I am a C++ pragma!" << getpid() << endl; 11 cout << "hello C++, I am a C++ pragma!" << getpid() << endl; 12 13 return 0; 14 }
1 #include <stdio.h>2 #include <unistd.h>3 #include <stdlib.h>4 #include <sys/types.h>5 #include <sys/wait.h>6 7 int main()8 {9 printf("testexec ... begin\n");10 11 pid_t id = fork();12 if(id == 0)13 {14 printf("child pid: %d\n", getpid()); 15 sleep(2);16 execl("./mypragma", "myprama", NULL);17 exit(1);18 }19 20 //father21 int status = 0;22 pid_t rid = waitpid(id, &status, 0);23 if(rid > 0)24 {25 printf("father wait sucess, child exit code: %d\n", WEXITSTATUS(status));26 }27 28 printf("testexec ... end!\n");29 return 0;30 }
[tt@kunkun testexec]$ ./testexec
testexec ... begin
child pid: 30468
hello C++, I am a C++ pragma!30468
hello C++, I am a C++ pragma!30468
hello C++, I am a C++ pragma!30468
hello C++, I am a C++ pragma!30468
father wait sucess, child exit code: 0
testexec ... end!
[tt@kunkun testexec]$ python
Python 2.7.5 (default, Nov 14 2023, 16:14:06)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> quit();
[tt@kunkun testexec]$ python
Python 2.7.5 (default, Nov 14 2023, 16:14:06)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> quit()
[tt@kunkun testexec]$ touch test.py
[tt@kunkun testexec]$ vim test.py
[tt@kunkun testexec]$ python3 test.py
hello python
hello python
hello python
hello python
shell脚本
1 #!/usr/bin/bash2 3 cnt=04 while [ $cnt -le 10 ]5 do6 echo "hello shell, cnt: ${cnt}"7 let cnt++8 done
[tt@kunkun testexec]$ bash test.sh
hello shell, cnt: 0
hello shell, cnt: 1
hello shell, cnt: 2
hello shell, cnt: 3
hello shell, cnt: 4
hello shell, cnt: 5
hello shell, cnt: 6
hello shell, cnt: 7
hello shell, cnt: 8
hello shell, cnt: 9
hello shell, cnt: 10
execl("/usr/bin/bash", "bash", "test.sh", NULL);
execl("/usr/bin/python", "python", "test.py", NULL);
[tt@kunkun testexec]$ chmod +x test.sh
[tt@kunkun testexec]$ chmod +x test.py
[tt@kunkun testexec]$ ll
total 44
-rw-rw-r-- 1 tt tt 159 Feb 20 15:49 Makefile
-rwxrwxr-x 1 tt tt 9128 Feb 20 16:00 mypragma
-rw-rw-r-- 1 tt tt 354 Feb 20 16:00 mypragma.cc
-rwxrwxr-x 1 tt tt 8720 Feb 20 16:00 testexec
-rw-rw-r-- 1 tt tt 569 Feb 20 16:01 testexec.c
-rwxrwxr-x 1 tt tt 107 Feb 20 16:05 test.py
-rwxrwxr-x 1 tt tt 103 Feb 20 16:29 test.sh
[tt@kunkun testexec]$ ./test.sh
hello shell, cnt: 0
hello shell, cnt: 1
hello shell, cnt: 2
hello shell, cnt: 3
hello shell, cnt: 4
hello shell, cnt: 5
hello shell, cnt: 6
hello shell, cnt: 7
hello shell, cnt: 8
hello shell, cnt: 9
hello shell, cnt: 10
[tt@kunkun testexec]$ ./test.py
hello python
hello python
hello python
hello python
1 #include <stdio.h>2 #include <unistd.h>3 #include <stdlib.h>4 #include <sys/types.h>5 #include <sys/wait.h>6 7 int main()8 {9 printf("testexec ... begin\n");10 11 pid_t id = fork();12 if(id == 0)13 {14 //我的父进程本身就有一批环境变量!!!,从bash来15 char *const argv[] = 16 {17 (char*)"mypragma",18 (char*)"-a",19 (char*)"-b",20 NULL21 };22 char *const envp[] =23 {24 (char*)"HAHA=111111",25 (char*)"HEHE=222222",26 NULL27 };28 extern char**environ; 29 printf("child pid: %d\n", getpid()); 30 sleep(2);31 execvpe("./mypragma", argv, environ);32 //execvpe("./mypragma", argv, envp);33 exit(1);34 }35 36 //father37 int status = 0;38 pid_t rid = waitpid(id, &status, 0);39 if(rid > 0)40 {41 printf("father wait sucess, child exit code: %d\n", WEXITSTATUS(status));42 }43 44 printf("testexec ... end!\n");45 return 0;46 }
1 #include <iostream>2 #include <unistd.h>3 4 using namespace std;5 6 int main(int argc, char *argv[], char *env[])7 {8 int i = 0;9 for(; argv[i]; i++)10 {11 printf("argv[%d] : %s\n", i, argv[i]);12 }13 14 printf("--------------------------------\n");15 for(i = 0; env[i]; i++)16 {17 printf("env[%d] : %s\n", i, env[i]);18 }19 printf("--------------------------------\n"); 20 cout << "hello C++, I am a C++ pragma!" << getpid() << endl;21 cout << "hello C++, I am a C++ pragma!" << getpid() << endl;22 cout << "hello C++, I am a C++ pragma!" << getpid() << endl;23 cout << "hello C++, I am a C++ pragma!" << getpid() << endl;24 25 return 0;26 }
putenv添加环境变量
#include <unistd.h>
int execve(const char *filename, char *const argv[], char *const envp[]);