【实践·专业课】进程管理与进程同步

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;
}
  1. 首先创建一个套接字(socket),指定地址族为 AF_INET(用于 IPv4 网络),套接字类型为 SOCK_STREAM(面向连接的可靠字节流,通常用于 TCP 协议)。
  2. 然后通过 bind 函数将套接字与本地地址(这里指定了 INADDR_ANY,表示可以接受来自任意本地网络接口的连接,端口号为 8080)绑定起来。
  3. 接着调用 listen 函数让服务器进入监听状态,允许最多 3 个客户端连接处于等待队列中。
  4. 当客户端发起连接请求后,通过 accept 函数接受连接,返回一个新的套接字描符 new_socket 用于与该客户端通信。
  5. 最后通过 read 函数从客户端接收消息,存放在 buffer 数组中,并输出接收到的消息内容,之后关闭与客户端通信的套接字以及服务器监听套接字。

2.2. 编写客户端程序

使用文本编辑器创建一个名为 client.c 的 C 文件,存储以下代码:

#include <
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值