761 字
4 分钟
C/C++进程的基础操作
2026-06-15

新进程的创建#

调用unistd.h库中的fork()语句,会创建一个新的子进程,在单核中,CPU的调度列表上会有两个进程,原有的父进程与新创建出的子进程,两进程并发执行,互不干扰;但是在子进程中,子进程会进行标记,将自身PID标记成为0,用于身份区分。

调用sys/types.h库下的pid_t类型,来显式定义新变量的类型。
(在大多数linux计算机中unistd.h库会自动链接sys/types.h库)

#include <unistd.h>
int main(){
pid_t pid = fork();
//也可以使用 int 来进行定义,但是可能会出现PID超出int上限的情况
return 0;
}

测试是否出创建了两个进程#

#include <iostream>
#include <unistd.h>
#include <sys/types.h>
using namespace std;
int main(){
pid_t pid = fork();
if(pid == 0) cout << "here is child process" << endl;
else cout << "here is parents process" << endl;
}

查看编译结果:#

编译结果
可以看到程序被父进程和子进程分别调用了一次。

自定义错误参数的返回#

在进程创建的过程中,当今进程创建失败时会弹出报错消息,此时我们可以利用unistd.h库下的perror函数,来对报错消息进行自定义注释。 例如:perror("进程创建失败!")

父进程接收子进程的返回值#

进程执行完毕后不会立即进行销毁,而是会进入类似阻塞状态并保留相对应的状态,因此需要调用unitsd.h库下的exit()函数进行资源解放。
同时sys/wait.h库下的wait()函数常与exit()函数进行配套使用,在父进程中调用wait()函数会将父进程进行阻塞,此时父进程会等待子进程的结束,并尝试接收子进程中主动调用exit()函数的返回值。

#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
using namespace std;
int main(){
pid_t pid = fork();
if(pid < 0){
perror("进程创建失败!");
}else if(pid == 0){
exit(1);
}else{
int status;
wait(&status);
cout << status;
}
}

编译并运行:#

编译结果
得到编译结果,此时我们发现返回值由1变成了256,这是因为内核为了在一个int类型中插入更多信息,因此对返回值进行了左移运算,左移了8位,因此从00000000 00000001变成了00000001 00000000,即从1变为了256

我们可以使用宏进行逆向操作 WEXITSTATUS()。 此时可以得到正确的值:

编译结果

如何获取PID#

直接说结论:

  • 获取自身PID: 在父进程中直接输出,在子进程中需要使用getpid()函数。
  • 获取父进程PID: 均需要使用getppid()函数。

对上文代码进行更新:

#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
using namespace std;
int main(){
pid_t pid = fork();
if(pid < 0){
perror("进程创建失败!");
}else if(pid == 0){
//new
cout << getpid() << ' '
<< getppid() << endl;
exit(1);
}else{
int status;
wait(&status);
cout << WEXITSTATUS(status);
//new
cout << pid << ' '
<< getppid();
}
}

查看编译结果:#

编译结果

可以看到已经成功打印了。

C/C++进程的基础操作
https://kuchikirei.github.io/posts/os1/
作者
LINKONG
发布于
2026-06-15
许可协议
CC BY-NC-SA 4.0