进程控制相关的几个函数

通常,创建新的进程,都是为了立即执行新的 ,不同的程序。

所以一般都是fork()系统调用创建新进程,然后使用exec()系统调用函数组,来创建新的地址空间,把新的程序载入进去。

最终,通过exit()系统调用退出进程,这个函数会终结进程,并释放该进程占用的资源。

父进程可以通过wait()系统调用,查看子进程是否结束。


下面是几个进程管理相关的几个函数:

1. 获取ID


#include <sys/types.h>
#include <unistd.h>
pid_t getpid(void)
获取本进程ID
pid_t getppid(void)
获取父进程ID

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(void)
{
        printf("PID = %d\n", getpid());
        printf("PPID = %d\n", getppid());
        return 0;

}

2. 创建进程-fork

#include <unistd.h>
pid_t fork(void)
功能:创建子进程
fork的奇妙之处在于它被调用一次,却返回2次,它可能有3种不同的返回值:
a. 在父进程中,fork返回新创建子进程的PID;

b. 在子进程中,fork返回0;

c. 如果出错,fork返回一个负值。

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

main()
{
        pid_t pid;

        //此时只有一个进程
        pid = fork();

        /* fork() 之后会有2个进程,下面的这段代码,会被父子2个进程都运行*/
        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", getppid());

}

在 pid=fork()之前,只有一个进程在执行,但这条语句之后,就变成了2个进程在执行了。
这两个进程共享代码段,将要执行的下一条语句都是if(pid == 0).
两个进程中,原来就存在的那个进程称为“父进程”,新出现的进程称为“子进程”。

父子进程的区别在于进程标识符(PID)不同。

#include <unistd.h>
#include <stdio.h>

int main(void)
{
        pid_t pid;
        int count = 0;

        pid = fork();

        count++;
        printf("count = %d\n", count);

        return 0;

}

子进程的数据空间,堆栈空间都会从父进程得到一个拷贝,而不是共享。
父子进程 代码段是共享的。

3. vfork()

#include <sys/types.h>
#include <unistd.h>
pid_t vfork(void)
功能: 创建子进程

#include <unistd.h>
#include <stdio.h>

int main(void)
{
        pid_t pid;
        int count = 0;

        pid = vfork();

        count++;
        printf("count = %d\n", count);

        return 0;

}

fork vs vfork

区别:
a.
fork: 子进程拷贝父进程数据段
vfork: 子进程与父进程共享数据段

b.
fork: 父进程,子进程的执行顺序不确定。
vfork: 子进程先运行,父进程后运行。


4. exec函数族

exec 用被执行程序替换调用它的程序,数据段,代码段都替换掉。
区别:
fork 创建一个新进程,产生一个新的PID;
exec 启动一个新程序,替换原有的进程,因此,进程PID不会变。

5.execl

#include <unistd.h>
int execl(const char * path, const char* arg1, ...)
参数:
path --- 被执行的程序名(含完整路径)。

arg1 - argn --- 被执行程序所需的命令行参数,含程序名。以空指针(NULL)结束。

#include <unistd.h>

main()
{
        execl("/bin/ls", "ls", "-al", "/etc/passwd", (char* )0);
}


6. execlp


#include <unistd.h>
int execlp(const char* path, const char* arg1, ...)
参数:
path --- 被执行程序名(不含路径,将从path环境变量中查找该程序)。
arg1-argn --- 被执行程序所需的命令行参数,含程序名。以空指针(NULL)结束。

#include <unistd.h>

main()
{
        execlp("ls", "ls", "-al", "/etc/passwd", (char* )0);
}

7. execv

#include <unistd.h>
int execv(const char* path, char* const argv[])
参数:
path --- 被执行程序名(含完整路径)。
argv[] --- 被执行程序所需的命令行参数数组。

#include <unistd.h>

main()
{
        char* argv[] = {"ls", "-al", "/etc/passwd", (char*)0};
        execv("/bin/ls", argv);
}

8. system函数


#include <stdlib.h>
int system(const char* string)
功能:
调用fork产生子进程,由子进程来调 “/bin/sh -c string“ 来执行参数 string 所指定的命令。

#include <stdlib.h>

void main()
{
        system("ls -al /etc/passwd");

}

9. 进程等待


#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status)
功能:
阻塞该进程,直到其某个子进程退出。

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

void main()
{
        pid_t pc, pr;

        pc = fork();

        if(pc == 0){ //子进程运行
                printf("This is child process with pid of %d\n", getpid());
                sleep(10); //睡眠10s
        }
        else if(pc > 0){ //父进程运行
                pr = wait(NULL); //等待子进程退出
                printf("I catched a child process with pid of %d\n", pr);
        }

        exit(0);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值