zoukankan      html  css  js  c++  java
  • 自测之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;
    }
    

      

  • 相关阅读:
    WCF Restful调用跨域解决方案
    [Asp.net]常见word,excel,ppt,pdf在线预览方案,有图有真相,总有一款适合你!
    人体呼吸信号的数据挖掘
    Spark编译及spark开发环境搭建
    诗两首------重庆项目出差有感
    eclipse安装和中文汉化,以及配置
    Querying CRM data with LINQ
    oracle pl/sql之在java中怎么调用oracle函数
    oracle pl/sql之oracle函数
    oracle pl/sql之java中调用oracle有参存储过程
  • 原文地址:https://www.cnblogs.com/xzxl/p/8533254.html
Copyright © 2011-2022 走看看