c语言代码题----linux

9 篇文章 0 订阅
9 篇文章 0 订阅

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;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jing静~

ლ(°◕‵ƹ′◕ლ)让我一键努

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值