目录
2,exec函数族 -----//在进程中加载另一个程序执行
程序是语句的集合
进程是程序的一次执行过程。
每一个进程都有一个唯一的ID,可以通过getpid()获取
例如:
#include
#include
int main(void)
{
while(1){
printf("%d\n",getpid());
sleep(1);
}
return 0;
}
进程和程序的区别
程序是静态的,它是一些保存在磁盘上的指令的有序集合,没有任何执行的概念
进程是一个动态的概念,它是程序执行的过程,包括创建、调度和消亡
进程是系统分配资源的最小单位
线程是cpu调度的最小单位
动态性 -----是程序的执行过程
并发性 -----多个进程可以同时运行
独立性 -----系统给每一个进程会分配独立的虚拟空间
异步性 ----- 进程之间各自运行,不会干扰
参考:3_进程的状态.tif
该类进程是由shell控制和运行的。交互进程既可以在前台运行,也可以在后台运行。
该类进程不属于某个终端,它被提交到一个队列中以便顺序执行。
例如: shell脚本程序
hello.sh
ls -l
pwd
touch abc.txt
该类进程在后台运行。它一般在Linux启动时开始执行,系统关闭时才结束。
#include
#include
pid_t vfork(void);//--子进程结束父进程再开始
pid_t fork(void);
//返回值--失败:-1,成功:给父进程返回子进程的ID,给子进程返回0 当调用fork()函数时,计算机会执行以下几步:
1》映射一个进程虚拟的内存空间,原来的进程称为父进程,新的虚拟空间中运行的进程称为子进程
2》将父进程所有数据段中的数据拷贝到子进程对应的段中
3》父子进程共享代码段
4》给父进程返回子进程的ID,给子进程返回0
5》父子进程从fork()函数调用的下一条语句同时开始运行。
例如:
- #include
- #include
- #include
- #include
-
- int main(void)
- {
- pid_t pid;
-
- pid = fork();
- if(pid < 0){
- perror("fork");
- exit(1);
- }if(pid > 0){
- //父进程执行
- printf("我是老子,我的ID:%d\n",getpid());
- while(1){
- printf("没事生孩子!\n");
- sleep(1);
- }
- }else{
- //子进程执行
- printf("我是儿子,我的ID:%d\n",getpid());
- while(1){
- printf("找个女朋友!\n");
- sleep(1);
- }
- }
- printf("hello world\n");
- return 0;
- }
#include
extern char **environ;
int execl(const char *path, const char *arg, .../* (char *) NULL */);
int execlp(const char *file, const char *arg, .../* (char *) NULL */);
int execle(const char *path, const char *arg, .../*, (char *) NULL, char * const envp[] */);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execve(const char *path, char *const argv[],char *const envp[]);
//添加环境变量---export PATH=$PATH:环境变量路径
例如:
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
-
- int main(void)
- {
- pid_t pid;
-
- if((pid = fork()) < 0){
- perror("fork");
- exit(1);
- }else if(pid > 0){
- while(1){
- printf("this is parent process!\n");
- sleep(1);
- }
-
- }else{
- #if 0
- execl("/bin/ls","ls","-l",NULL);
- execlp("ls","ls","-l",NULL);
- char * env[] = {"name=jack","passwd=123",NULL};
- execle("./envtest","./envtest",NULL,env);
- char *arg[] = {"ls","-l",NULL};
- //execv("/bin/ls",arg);
- //execvp("ls",arg);
- #else
- char *arg[] = {"./envtest",NULL};
- char * env[] = {"name=jack","passwd=123",NULL};
- execve("./envtest",arg,env);
- #endif
- //执行exec函数族后,后面的代码全部被加载的另一个程序替换,所以无法执行的
- }
- return 0;
- }
-
- //加载自己写的打印环境变量的程序,代码如下:
- #include <stdio.h>
-
- extern char **environ;
- int main(void)
- {
- int i;
-
- for(i = 0; environ[i]!= NULL; i++)
- printf("%s\n",environ[i]);
- return 0;
- }
#include
void _exit(int status); //直接结束进程
例如:
- int main(void)
- {
- printf("hello world");
- _exit(0); //结束程序,不刷新缓冲区,所以hello world不能显示在屏幕上
- return 0;
- }
-
-
- #include <stdlib.h>
- void exit(int status); //结束进程之前,会先刷新缓冲区,并释放资源
- 例如:
- int main(void)
- {
- printf("hello world");
- exit(0); //结束进程之前,会先刷新缓冲区,并释放资源,所以hello world可以显示在屏幕上
- return 0; //在main()函数中,执行return时,会自动调用exit();
- }
#include
#include
pid_t getppid(void); //获取当前进程的父进程pid
例如:
- #include
- #include
- #include
-
- int main(void)
- {
- printf("父进程ID = %d\n",getppid());
- printf("进程ID = %d\n",getpid());
- return 0;
- }
#include
#include
pid_t wait(int *wstatus);
//参数 ------ 获取子进程结束的状态
//返回值 ---成功:收尸的子进程pid,失败:-1
//当调用wait()给子进程收尸时:
1)如果父进程没有子进程,则wait()立即返回
2)如果子进程尚未结束,则wait()使父进程阻塞,直到有一个子进程结束时返回。
3)如果子进程已经结束,则wait()立即返回
例如:
- #include
- #include
- #include
- #include
- #include
-
- int main(void)
- {
- pid_t pid;
-
- if((pid = fork()) < 0){
- perror("fork");
- exit(1);
- }else if(pid > 0){
- int wstatus;
- //wait(NULL);
- wait(&wstatus);
- printf("%d\n",WEXITSTATUS(wstatus));
- printf("helo world\n");
- printf("父进程:pid = %d\n",getpid());
- printf("父进程:ppid = %d\n",getppid());
- }else{
- printf("hello world\n");
- printf("子进程:pid = %d\n",getpid());
- printf("子进程:ppid = %d\n",getppid());
- exit(89);
- }
- return 0;
- }
//给指定的子进程收尸
pid_t waitpid(pid_t pid, int *wstatus, int options);
//参数1 ---- 指定的子进程pid:
pid > 0,给指定的子进程收尸
pid=-1:等待任何一个子进程退出,此时和wait作用一样。
pid=0:等待其组ID等于调用进程的组ID的任一子进程。
pid<-1:等待其组ID等于pid的绝对值的任一子进程。
//参数2 ---- 子进程结束状态
//参数3 ----- wait的选项,一般为0
//返回值 -----成功:收尸的子进程pid,失败:-1
例如:
- int main(void)
- {
- pid_t pid1,pid2;
- int i;
-
- //创建子进程1
- if((pid1 = fork()) < 0){
- perror("fork");
- exit(1);
- }else if(!pid1){
- //子进程1
- for(i = 0; i < 5; i++){
- printf("我是子进程1\n");
- sleep(1);
- }
- exit(0);
- }
- //创建子进程2
- if((pid2 = fork()) < 0){
- perror("fork");
- exit(1);
- }else if(!pid2){
- //子进程2
- for(i = 0; i < 9; i++){
- printf("我是子进程2\n");
- sleep(1);
- }
- exit(0);
- }
- //父进程
- waitpid(pid1,NULL,0);
- printf("我是父进程!\n");
-
- return 0;
- }