1. 创建进程
1.1. 准备环境
打开终端,输入以下命令检查系统中是否已经安装了 GCC
编译器:
gcc --version
winky@winky-virtual-machine:~$ gcc --version
gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
显示已经安装
11.4.0
版本的GCC。
1.2. 编写程序
使用文本编辑器vim
创建一个名为 create_process.c
的 C 文件。先在终端中输入以下命令来启动 Vim 并创建一个新的文件
vim create_process.c
再按下 i
键进入插入模式(insert mode) 。
在插入模式下,输入代码:
#include <stdio.h>
#include <unistd.h>
int main() {
pid_t pid = fork(); // 创建新的进程
if (pid < 0) {
perror("fork failed");
return 1;
} else if (pid == 0) {
printf("This is the child process with PID %d\n", getpid());
} else {
printf("This is the parent process with PID %d\n", getpid());
}
return 0;
}
代码中通过
fork()
系统调用创建一个新的进程。fork()
函数返回值有三种情况:
- 若返回值小于
0
,表示创建子进程失败,会输出错误提示信息并返回1
。- 若返回值等于
0
,则代表当前处于新创建的子进程中,会输出表明子进程身份以及其进程 ID(通过getpid()
函数获取)的消息。- 若返回值大于
0
,表示当前处于父进程中,返回值就是新创建子进程的进程 ID,这里输出表明父进程身份以及其进程 ID 的消息。
完成代码编写后,按下 Esc
键退出插入模式,返回到普通模式。然后输入 :wq
并按回车键保存文件并退出 Vim。
1.3. 编译程序
在保存 create_process.c
文件的目录下,打开终端,输入以下编译命令来使用 GCC 编译器来编译这个 C 文件,并运行生成的可执行文件
gcc create_process.c -o create_process
1.4. 运行程序
在终端中,执行以下命令来运行编译好的可执行文件:
./create_process
运行后,我看到终端输出两条消息,一条是父进程相关的消息,表明父进程的身份以及其进程 ID,另一条是子进程相关的消息,表明子进程的身份以及其进程 ID。
每次运行时进程 ID 的具体数值会不同,它是由操作系统动态分配的。
2. 进程通信(Socket机制)
2.1. 编写服务器端程序
使用文本编辑器vim创建一个名为 server.c
的 C 文件,存储以下代码:
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#define PORT 8080
int main() {
int server_fd, new_socket;
struct sockaddr_in address;
int addrlen = sizeof(address);
char buffer[1024] = {0};
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("socket failed");
return 1;
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("bind failed");
close(server_fd);
return 1;
}
if (listen(server_fd, 3) < 0) {
perror("listen failed");
close(server_fd);
return 1;
}
if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
(socklen_t*)&addrlen)) < 0) {
perror("accept failed");
close(server_fd);
return 1;
}
read(new_socket, buffer, 1024);
printf("Message from client: %s\n", buffer);
close(new_socket);
close(server_fd);
return 0;
}
- 首先创建一个套接字(
socket
),指定地址族为AF_INET
(用于 IPv4 网络),套接字类型为SOCK_STREAM
(面向连接的可靠字节流,通常用于 TCP 协议)。- 然后通过
bind
函数将套接字与本地地址(这里指定了INADDR_ANY
,表示可以接受来自任意本地网络接口的连接,端口号为8080
)绑定起来。- 接着调用
listen
函数让服务器进入监听状态,允许最多3
个客户端连接处于等待队列中。- 当客户端发起连接请求后,通过
accept
函数接受连接,返回一个新的套接字描符new_socket
用于与该客户端通信。- 最后通过
read
函数从客户端接收消息,存放在buffer
数组中,并输出接收到的消息内容,之后关闭与客户端通信的套接字以及服务器监听套接字。
2.2. 编写客户端程序
使用文本编辑器创建一个名为 client.c
的 C 文件,存储以下代码:
#include <