进程是操作系统结构的基础。进程是一个具有独立功能的程序对某个数据集在处理机上的执行过程,进程也是作为资源分配的一个基本单位。Linux作为一个多用户、多任务的操作系统,必定支持多进程。多进程是现代操作系统的基本特征。一个进程也可以通俗理解为就是我们运行的一个独立的程序。
一个程序可以有多个进程,每个进程都会有个唯一的标志符,PID,就像我们身份证一样。PID是进程运行时系统随机分配的,在进程运行时,PID是不会改变的,进程终止后,PID就会被系统回收。
进程的创建
实际项目中我们很少在一个编译项目中创建多个进程,多进程一般体现在不同编译工程,每个工程都是独立的,一般就是某类服务器,多个服务一起工作,就构建出多进程环境。从而可以引申出负载均衡,分布式部署等技术解决方案。一个服务一般是单进程多线程模型。
1.使用fork创建进程
Linux可以通过执行系统调用函数fork来创建新进程。由fork创建的新进程被称为子进程。该函数调用一次,但返回两次。两次返回的区别是在子进程中返回值是0,而在父进程中返回值是子进程的PID。如果失败,则在父进程程序中返回-1,并且可以通过errno得到错误码。这个函数相当于克隆一个进程。 从调用fork之后代码复制了一份,父,子进程分开执行后面代码,先后顺序无规律,由系统分配。
#include <iostream>
using namespace std;
#include <unistd.h>
#include <stdio.h>
int main()
{
pid_t fpid;
int count = 0;
fpid = fork();
if(fpid < 0){
cout << "failed to fork";
} else if(fpid == 0){
cout << "I am the child process, my pid is " << getpid() << endl;
count++;
} else {
cout << "I am the parent process, my pid is " << getpid() << endl;
cout << "fpid = " << fpid << endl;
count++;
}
printf("result: %d\n", count);
return 0;
}
输出:
2.使用exec创建进程
exec就是在调用进程(调用exec函数的进程)内部执行一个可执行文件。这里的可执行文件可以是二进制文件,也可以是任何Linux下可执行的脚步文件。相当于借一个壳运行,exec启动的新进程替换当前进程,且PID不变。
#include <unistd.h>
int main()
{
execl("/bin/pwd", "abcdef", NULL);
return 0;
}
编译运行这个程序,相当于执行了pwd命令一样。
3.使用system创建进程
system函数通过调用shell程序来执行所传入的命令(效率低),相当于先fork(),在exec,且源进程需要等子进程运行完后再继续。
其源码具体实现步骤:
(1)fork一个子进程。
(2)在子进程中调用exec函数去执行command命令(system函数参数)。
(3)在父进程中调用wait等待子进程结束。如果fork失败,system()返回-1。如果exec执行成功,则返回command通过exit或return返回的值。如果exec执行失败,system()函数返回127。如果command为NULL,则system()返回非0值,一般为1.
int system(const char * cmdstring)
{
pid_t pid;
int status;
if(cmdstring == NULL){
return (1);
}
if((pid = fork())<0){
status = -1;
} else if(pid == 0){
execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
_exit(127);
} else{
while(waitpid(pid, &status, 0) < 0){
if(errno != EINTER){
status = -1;
break;
}
}
}
return status;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)