c - 先进先出执行流程系统

标签 c process fifo

我正在尝试学习 C 语言的进程,我认为我理解了管道的逻辑,但无法理解 fifo,即使我读了很多相关内容。我最近使用管道编写了一个程序,该程序从标准输入中获取一个字符串,将其写入管道1,检查它是否是字母数字,如果是,则管道3读取它并显示它。如果字符串仅包含数字,则 pipeline2 会读取它并用 _ 替换数字,然后 pipeline4 会读取新字符串并显示它。 我把它放在这里,因为我想使用 fifo 做类似的事情:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<string.h>
#include<sys/wait.h>
#include<ctype.h>

int main()
{
int p1[2];
int p2[2];
int p3[2];
int p4[2];

char input_str[100];
pid_t fork1;
pid_t fork2;

if (pipe(p1)==-1)
{
    fprintf(stderr, "Pipe Failed" );
    return 1;
}
if (pipe(p2)==-1)
{
    fprintf(stderr, "Pipe Failed" );
    return 1;
}
if (pipe(p3)==-1)
{
    fprintf(stderr, "Pipe Failed" );
    return 1;
}
if (pipe(p4)==-1)
{
    fprintf(stderr, "Pipe Failed" );
    return 1;
}


scanf("%s", input_str);

int isAlpha = 0; 
int onlyDigits = 0; 
for (int i=0; input_str[i]!= '\0'; i++) 
{

    if (isalpha(input_str[i]) != 0) {
        isAlpha = 1;
        onlyDigits = 0;
    }
    else if (isdigit(input_str[i]) != 0) {
        isAlpha = 1;
        onlyDigits = 1;
    }
    else { 
        isAlpha = 0;
        onlyDigits = 0;
    }
}


fork1 = fork();
if (fork1 < 0)
{
    fprintf(stderr, "fork Failed" );
    return 1;
}


else if (fork1 > 0)
{
    close(p1[0]); 
    write(p1[1], input_str, strlen(input_str)+1);
}


else
{
    close(p1[1]);
    char string_from_p1[100];
    read(p1[0], string_from_p1, 100);
    close(p1[0]);
    fork2 = fork();
    if (onlyDigits) {
        for (int i=0; string_from_p1[i]!= '\0'; i++) {
            if (isdigit(string_from_p1[i]) != 0)
                string_from_p1[i] = '_';
        }
        write(p2[1], string_from_p1, strlen(string_from_p1)+1);
    }
    else if (isAlpha) {
        write(p3[1], string_from_p1, strlen(string_from_p1)+1);
    }
    if (fork2 < 0) {
            fprintf(stderr, "fork Failed" );
            return 1;
    }
    else if (fork2 > 0) {
        char string_from_p2[100];
        char string_from_p3[100];
        char string_from_p4[100];
        if (onlyDigits) {
            close(p2[1]);
            read(p2[0], string_from_p2, 100);
            close(p2[0]);
            write(p4[1], string_from_p2, strlen(string_from_p2)+1);
            close(p4[1]);
            read(p4[0], string_from_p4, 100);
            printf("String from pipe4: %s\n", string_from_p4);
        }
        else if (isAlpha) {
            close(p3[1]);
            read(p3[0], string_from_p3, 100);
            printf("String from pipe3: %s\n", string_from_p3);
        }
    }
exit(0);
}
}

不确定这有多正确,但是 FIFO 程序只有 3 个进程,它首先从最多 30 个字符的标准输入行中读取,在第一个导出(process2)中写入数字,在第二个导出(process3)中写入字母。然后在process2中只显示结果(找到的数字),在process3中将小写字母变成大写字母并显示结果。

有人可以帮我吗?

最佳答案

作为起点,您可以尝试这样的事情(大多数功能仍需要实现,请参阅评论):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <ctype.h>

void read_and_write(const char *digits_fifo, const char *chars_fifo);
pid_t spawn_digits_child(const char *digits_fifo);
pid_t spawn_chars_child(const char *chars_fifo);
void digits_child(const char *digits_fifo);
void chars_child(const char *chars_fifo);
void wait_until_children_finish(pid_t pid1, pid_t pid2);

#define MAX_INPUT 30

int main() {
    char *digits_fifo = "/tmp/digits_fifo";
    char *chars_fifo = "/tmp/chars_fifo";

    mkfifo(digits_fifo, 0666);
    mkfifo(chars_fifo, 0666);

    //fork digits process
    pid_t pid_digits = spawn_digits_child(digits_fifo);

    //fork chars process
    pid_t pid_chars = spawn_chars_child(chars_fifo);

    //parent
    read_and_write(digits_fifo, chars_fifo);
    wait_until_children_finish(pid_digits, pid_chars);
    exit(0);
}

pid_t spawn_digits_child(const char *digits_fifo) {
    pid_t pid1;
    if ((pid1 = fork()) < 0) {
        fprintf(stderr, "fork error digits process\n");
        exit(-1);
    } else if (pid1 == 0) {
        digits_child(digits_fifo);
        exit(0);
    }
    return pid1;
}

pid_t spawn_chars_child(const char *chars_fifo) {
    //do sth similar then in spawn_digits_child but for chars child process
}

void wait_until_children_finish(pid_t pid1, pid_t pid2) {
    //use waitpid to wait for child process termination
}

void read_and_write(const char *digits_fifo, const char *chars_fifo) {
    //read input string 
    //open the two named pipes with O_WRONLY
    //check with isdigit respective isalpha and send to the corresponding named pipe
    //don't forget to close file handles
}

void chars_child(const char *chars_fifo) {
    //open named piped with O_RDONLY
    //e.g. int chars_fd = open(chars_fifo, O_RDONLY);
    //read from pipe
    //do uppercase string
    //output it with printf
}

void digits_child(const char *digits_fifo) {
    //open named piped with O_RDONLY
    //e.g. int chars_fd = open(digits_fifo, O_RDONLY);
    //read from pipe
    //output it with printf
}

关于c - 先进先出执行流程系统,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56268050/

相关文章:

c - 稀疏抛出的警告

c - 在 c 中使用 srand() 生成大数

c - 简单的 C 音频库

C - HoneSTLy 对这种奇怪的行为感到不知所措

java - 在内存文件中作为在 Linux 上的 Java 中处理的参数

考虑给出的 `fork` 程序,以下程序打印 hello 多少次?

MySQL 与 FIFO 的限制关系表

process - 在 elixir 中创建一个假的或虚拟的 pid

caching - clojure 向量缓存

c++ - 两个不同进程c++之间的FIFO通信