自测之Lesson10:管道

题目:建立双向管道,实现:父进程向子进程传送一个字符串,子进程对该字符串进行处理(小写字母转为大写字母)后再传回父进程。

实现代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

void TestPipeDouble()
{
        pid_t pid;
        int fd_A[2], fd_B[2];
        if (pipe(fd_A) || pipe(fd_B)) {         // 创建管道A和管道B
                perror("pipe fail");
                return;
        }
        char szBuf[1024];
        pid = fork();
        if (pid == 0) {
                close(fd_A[1]);
                close(fd_B[0]);
                printf("Child pid:%d
", getpid());
                while(1) {
                        memset(szBuf, 0, 1024);
                        read(fd_A[0], szBuf, 1024);
                        int i;
                        for (i = 0; i < strlen(szBuf); ++i) {
                                if (szBuf[i] <= 'z' && szBuf[i] >= 'a') {
                                        szBuf[i] += ('A' - 'a');
                                }
                        }
                        write(fd_B[1], szBuf, strlen(szBuf));
                }
                close(fd_A[0]);
                close(fd_B[1]);
        }
        else {
                close(fd_A[0]);
                close(fd_B[1]);
                printf("Father pid:%d
", getpid());
                while(1) {
                        usleep(1000);
                        printf("Send:");
                        scanf("%s", szBuf);
                        write(fd_A[1], szBuf, strlen(szBuf));
                        memset(szBuf, 0, 1024);
                        read(fd_B[0], szBuf, 1024);
                        printf("Recv:%s
", szBuf);
                }
                close(fd_A[1]);
                close(fd_B[0]);
        }

}


int main()
{
        TestPipeDouble();
        return 0;
}

题目:基于管道,并借助于dup2、exec函数族,实现命令“ps -ef | grep pipe”。

实现代码:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>


// 相当于“ps -ef | grep pipe”
void TestPipeRedir()            // 重定向
{
        int fd[2];
        pid_t pid;
        if(pipe(fd) == -1) {
                perror("pipe failed");
                return;
        }
        pid = fork();
        if (pid == 0) {
                dup2(fd[1], STDOUT_FILENO);     // 将本应输出至stdout的“ls -l”,转而输出至管道写端
                close(fd[0]);
                close(fd[1]);
                execlp("ps", "ps", "-ef", NULL);        // 参数列表以NULL结尾
        }
        else {
                dup2(fd[0], STDIN_FILENO);      // grep本应由stdin读入“ls -l”, 转而从管道读端读入
                close(fd[0]);
                close(fd[1]);
                execlp("grep", "grep", "pipe", NULL);
        }
}

int main()
{
        TestPipeRedir();
        return 0;
}

题目:使用popen函数实现命令“ps -ef | grep pipe”。

实现代码:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

/* 使用sort对数组arr进行排序 */
void TestPipePopen_easy()
{
        int arr[] = {2, 3, 7, 3, 5, 10, 9};
        FILE *pFile = popen("sort -n", "w");    // 当前进程将arr传入子进程sort
        int i;
        for (i = 0; i != sizeof(arr) / sizeof(int); i++) {
                fprintf(pFile, "%d
", arr[i]); // 父进程通过pFile来发送数据至子进程
        }
        pclose(pFile);                          // 一旦pclose,即开始执行sort命令
}

/* 实现命令ps -ef | grep pipe  */
void TestPipePopen_complex()
{
        FILE *pRead = popen("ps -ef", "r");             // 子进程ps将数据写入当前进程
        FILE *pWrite = popen("grep pipe", "w");         // 当前进程将数据写入子进程grep
        char szBuf[1024];
        while(fgets(szBuf, 1024, pRead))                // 逐行读取
        {
                fputs(szBuf, pWrite);

        }
        pclose(pRead);
        pclose(pWrite);
}

int main()
{
        TestPipePopen_easy();
        TestPipePopen_complex();
        return 0;
}

  

题目:通过命名管道实现任意两个进程间通信(一个进程在读,另一个在写)。

实现代码:

/*
 *  命名管道
 *  进程间通信————任意两个进程
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <fcntl.h>

void ReadFifo(int fd) 
{
        char szBuf[1024];
        while (1) {
                memset(szBuf, 0, 1024);
                read(fd, szBuf, 1024);
                printf("Process[PID:%d] Recv:%s
", getpid(), szBuf);
                if (strcmp(szBuf, "exit") == 0) {
                        return;
                }
        }
}

void WriteFifo(int fd) 
{
        char szBuf[1024];
        while (1) {
                setbuf(stdout, NULL);
                printf("Process[PID:%d]Send:", getpid());
                scanf("%s", szBuf);
                write(fd, szBuf, strlen(szBuf));
                if (strcmp("exit", szBuf) == 0) {
                        return;
                }
        }
}

int main(int argc, char **argv)
{
        if (argc != 3) {
                printf("usage: %s [r | w] filename
", argv[0]);
                printf("	r: read the fifo
");
                printf("	w: write the fifo
");
                printf("	filename: the fifo file name
");
                return -1;
        }
        int fd;
        struct stat info;
        stat(argv[2], &info);
        if (!S_ISFIFO(info.st_mode)) {  // 判断是否为管道文件
                printf("this file is not fifo
");
                return -1;
        }
        if (argv[1][0] == 'r') {
                fd = open(argv[2], O_RDONLY);    // 打开管道文件
                if (fd < 0){
                        perror("open fail");
                        return -1;
                }
                ReadFifo(fd);
        }
        else if (argv[1][0] == 'w') {
                fd = open(argv[2], O_WRONLY);
                if (fd < 0) {
                        perror("open fail");
                        return -1;
                }
                WriteFifo(fd);
        }
        close(fd);
        return 0;
}

  

原文地址:https://www.cnblogs.com/xzxl/p/8533254.html