3.利用fifo 实现不相关的两个进程之间,互相传递各自的PID 给对方。
下面是使用命名管道(FIFO)在两个不相关的进程之间互相传递各自PID的示例代码。我们将创建两个程序:一个发送者(sender)和一个接收者(receiver)。发送者将创建FIFO,并写入其PID;接收者将读取发送者的PID,并写入自己的PID。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#define FIFO_PATH "/tmp/my_fifo"
int main() {
int fifo_fd;
char buffer[100];
int bytes_read;
pid_t pid;
// 创建FIFO
if (mkfifo(FIFO_PATH, 0666) == -1) {
perror("mkfifo");
exit(EXIT_FAILURE);
}
// 打开FIFO进行写入
fifo_fd = open(FIFO_PATH, O_WRONLY);
if (fifo_fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
// 获取当前进程的PID
pid = getpid();
sprintf(buffer, "%d", pid);
// 写入PID到FIFO
if (write(fifo_fd, buffer, strlen(buffer)) == -1) {
perror("write");
exit(EXIT_FAILURE);
}
// 关闭FIFO
close(fifo_fd);
// 打开FIFO进行读取
fifo_fd = open(FIFO_PATH, O_RDONLY);
if (fifo_fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
// 读取接收者进程的PID
bytes_read = read(fifo_fd, buffer, sizeof(buffer));
if (bytes_read == -1) {
perror("read");
exit(EXIT_FAILURE);
}
// 输出接收者进程的PID
printf("Receiver's PID: %s\n", buffer);
// 关闭FIFO
close(fifo_fd);
// 删除FIFO
unlink(FIFO_PATH);
return 0;
}
下来是接收者程序的代码(保存为 receiver.c
):
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#define FIFO_PATH "/tmp/my_fifo"
int main() {
int fifo_fd;
char buffer[100];
int bytes_read;
pid_t pid;
// 打开FIFO进行读取
fifo_fd = open(FIFO_PATH, O_RDONLY);
if (fifo_fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
// 读取发送者进程的PID
bytes_read = read(fifo_fd, buffer, sizeof(buffer));
if (bytes_read == -1) {
perror("read");
exit(EXIT_FAILURE);
}
// 输出发送者进程的PID
printf("Sender's PID: %s\n", buffer);
// 关闭FIFO
close(fifo_fd);
// 获取当前进程的PID
pid = getpid();
sprintf(buffer, "%d", pid);
// 打开FIFO进行写入
fifo_fd = open(FIFO_PATH, O_WRONLY);
if (fifo_fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
// 写入PID到FIFO
if (write(fifo_fd, buffer, strlen(buffer)) == -1) {
perror("write");
exit(EXIT_FAILURE);
}
// 关闭FIFO
close(fifo_fd);
return 0;
}
编译连个程序
gcc sender.c -o sender
gcc receiver.c -o receiver
运行
./sender &
./receiver
注意,发送者程序创建FIFO,写入其PID,然后等待接收者读取并写入其PID。接收者程序读取发送者的PID,写入自己的PID,然后两个程序都可以输出对方的PID。
确保在运行接收者之前运行发送者,因为发送者负责创建FIFO。使用 &
在后台运行发送者可以使得两个程序几乎同时运行。在真实环境中,可能需要更复杂的同步机制来确保两个进程按正确的顺序执行。
父子进程分别实现对同一目录下的内容进行统计,要求子进程统计子文件个数,父进程统计子目录个数,并且分别将结果
传递给对方进行输出;
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <dirent.h>
#include <string.h>
#define DIR_PATH "." // 定义要统计的目录路径为当前目录
int count_files(DIR *dirp) {
struct dirent *entry;
int file_count = 0;
while ((entry = readdir(dirp)) != NULL) {
// 忽略当前目录和上级目录
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
// 判断是否为文件
if (entry->d_type == DT_REG) {
file_count++;
}
}
return file_count;
}
int count_directories(DIR *dirp) {
struct dirent *entry;
int dir_count = 0;
while ((entry = readdir(dirp)) != NULL) {
// 忽略当前目录和上级目录
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
// 判断是否为目录
if (entry->d_type == DT_DIR) {
dir_count++;
}
}
return dir_count;
}
int main() {
pid_t pid;
int pipe_fds[2];
int file_count, dir_count;
// 创建管道
if (pipe(pipe_fds) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
// 创建子进程
pid = fork();
if (pid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (pid == 0) { // 子进程
// 关闭不需要的管道写端
close(pipe_fds[1]);
DIR *dirp = opendir(DIR_PATH);
if (dirp == NULL) {
perror("opendir");
exit(EXIT_FAILURE);
}
file_count = count_files(dirp);
closedir(dirp);
// 读取父进程发送的目录数量
read(pipe_fds[0], &dir_count, sizeof(dir_count));
printf("Number of files: %d\n", file_count);
printf("Number of directories: %d\n", dir_count);
// 关闭管道读端
close(pipe_fds[0]);
} else { // 父进程
// 关闭不需要的管道读端
close(pipe_fds[0]);
DIR *dirp = opendir(DIR_PATH);
if (dirp == NULL) {
perror("opendir");
exit(EXIT_FAILURE);
}
dir_count = count_directories(dirp);
closedir(dirp);
// 发送目录数量给子进程
write(pipe_fds[1], &dir_count, sizeof(dir_count));
// 等待子进程结束
wait(NULL);
// 读取子进程发送的文件数量
read(pipe_fds[1], &file_count, sizeof(file_count));
printf("Number of directories: %d\n", dir_count);
printf("Number of files: %d\n", file_count);
// 关闭管道写端
close(pipe_fds[1]);
}
return 0;
}