2021-02-28

LINUX系统进程相关的API

在LINUX系统下可以用ps指令来查看系统的进程
在实际工作中经常使用 ps -aux|gep 程序名,就可以查看目标程序的进程。也可以用top指令查看,相当于windows系统下的任务管理器。
每个进程都有自己的进程代码,用getpid函数可以获取当前经常的进程号

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main()
{
        pid_t pid;
        pid = getpid();

        fork();

        printf("my pid is %d\n",pid);
        return 0;
}

使用fork()函数创建一个进程

pid_t fork(void);
fork函数调用成功,返回两次。返回值为0代表当前进程是子进程。返回值为1代表当前进程是父进程。
调用失败返回-1。
使用fotk函数相当于创建了一个子进程,原先的进程是父进程。父子进程会同时运行fork包含的内容,且父子进程不相互干扰。
fork创建一个子进程的一般目的:
1 一个父进程希望复制自己,使父,子进程同时执行不同的代码段。这在网络服务进程中常见的——父进程等待客户端的服务请求。当这种请求到达时,父进程调用fork,使子进程处理次请求。父进程则继续等待下一个服务请求到达。
2 一个进程要执行一个不同的程序。这对shell是常见的情况。在这种情况下,子进程从fork返回后立即调用exec。

vfork函数,也可以创建进程。它与fork函数的区别
1 vfork 直接使用父进程储存空间,不拷贝。
2 vfork保证子进程先运行,当子进程调用exit退出后,父进程才执行。

进程的退出

正常退出
1 Main函数调用return
2 进程调用exit(),标准c库
3 进程调用_exit()或者_Exit(),属于系统调用
异常退出
1 调用abort
2 当进程收到某些信号时,如ctrl+c
3最后一个线程对取消(cancellation)请求做出响应
pid_t wait(int *status);父进程等待子进程
wait函数是用来父进程等待子进程退出并收集进程的退出状态。如果子进程退出状态不被收集,变成死进程(僵尸进程)。
可以根据函数的收集状态来判断子进程的执行状态。
status参数:是一个整形指针
非空:子进程退出状态放在它所指向的地址中。
空:不关心退出状态

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>

int main()
{
        pid_t pid;
        int cnt =0;
        int status=10;

        pid = fork();

        if(pid>0)
        {
                wait(&status);
                printf("child quit,child status=%d\n",WEXITSTATUS(status));
                while(1){
                        printf("cnt=%d\n",cnt);
                        printf("this is father print,pid =%d\n",getpid());
                        sleep(1);
                }
        }
        else if(pid==0){
                while(1){
                        printf("this is child print. pid=%d\n",getpid());
                        sleep(1);
                        cnt++;
                        if(cnt==5){
                                exit(3);
                        }
                }
        }


        return 0;

}

wait函数如果其所有子进程都还在运行,则阻塞。如果一个子进程已终止,正等待父进程获取其终止状态,则去得该子进程的终止状态立即返回。如果它没有任何子进程,则立即出错。

pid_t waitpid(pid_t pid,int *status,int options)
从本质上讲,系统调用waitpid和wait的作用是完全相同的,但waitpid多出了两个可由用户控制的参数pid和options,从而为我们编程提供了另一种更灵活的方式。下面我们就来详细介绍一下这两个参数:
pid

从参数的名字pid和类型pid_t中就可以看出,这里需要的是一个进程ID。但当pid取不同的值时,在这里有不同的意义。
1 pid>0时,只等待进程ID等于pid的子进程,不管其它已经有多少子进程运行结束退出了,只要指定的子进程还没有结束,waitpid就会一直等下去。
2 pid=-1时,等待任何一个子进程退出,没有任何限制,此时waitpid和wait的作用一模一样。
3 pid=0时,等待同一个进程组中的任何子进程,如果子进程已经加入了别的进程组,waitpid不会对它做任何理睬。
4 pid<-1时,等待一个指定进程组中的任何子进程,这个进程组的ID等于pid的绝对值。
wait函数的详细用法

linux进程下的exec族函数

exec函数是可以用来在一个程序中调用另一个程序
exec族函数的用法
exec族函数可以与fork函数配合使用主要作用有
1 一个父进程希望复制自己,使父,子进程同时执行不同的代码段。这在网络服务进程中是常见的——父进程等待客户端的服务请求。当这种请求到达时,父进程调用fork,使子进程处理此请求。父进程则继续等待下一个服务请求到达。
2 一个进程要执行一个不同的程序。这对shell是常见的情况。在这种情况下,子进程从fork返回后立即调用exec。
实现功能,当父进程检测到输入为1的时候,创建子进程把配置文件的字段值修改掉。

LINUX system函数

system函数
他与exec的功能相似,都是用来在程序中执行另一个程序。它比exec更简单更粗暴。

LINUX popen函数

popen函数
它比system在应用中的好处是可以获取运行的输出结果。
此函数执行的结果被存放起来,可以通过fread函数来读出来。换句话说此函数的执行信息能够传递。

上一篇:Redis的持久化RDB,fork,copyonwrite,AOF


下一篇:【效率开发】神奇的github搜索栏