操作系统 实验30 管道通信

 

1、匿名管道通信

源程序:

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

int wc=1,rc=1;
char wstr[100]; // 在此处声明了全局变量wstr

void writer (const char* message, int count, FILE* stream)
{
	for (; count > 0; --count) {
		fprintf (stream, "%s:%d\n", message,wc);
		sprintf(wstr,"%s:%d\n", message,wc);
		fflush (stream);
		printf("第%d次写入管道的内容为:%s",wc,wstr);
		wc++;
		sleep (1);
	}
}

void reader (FILE* stream)
{
	char buffer[1024];
	while (!feof (stream) && !ferror (stream) && fgets (buffer, sizeof (buffer), stream) != NULL)
	{
		printf("读进程第%d次读取:",rc);
		rc++;
		fputs (buffer, stdout);
	}
}

int main ()
{
	int fds[2];
	pid_t pid;
	pipe (fds);
	pid = fork ();
	if (pid == (pid_t) 0) {
		FILE* stream;
		close (fds[1]);
		stream = fdopen (fds[0], "r");
		reader (stream);
		close (fds[0]);
	}
	else {
		FILE* stream;
		close (fds[0]);
		stream = fdopen (fds[1], "w");
		writer ("Hello, world.", 5, stream);
		close (fds[1]);
	}
	return 0;
}

编译链接命令:gcc pipec.c -o pipec

运行命令:./pipec

交互与结果:

2、有名管道通信

源程序:

fifo_write.c

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <sys/types.h>  
#include <sys/stat.h>  
#include <fcntl.h>  
#include <unistd.h>  
#include <errno.h>  
  
#define FIFO "myfifo" // 有名管道名字  
#define BUFF_SIZE 1024  
  
int main(int argc, char *argv[]) {  
    char buff[BUFF_SIZE]; // 欲写入管道的数据缓冲区  
    ssize_t real_write; // 写入管道的字节数,使用ssize_t代替int  
    int fd; // 管道描述符  
    int rw = 1; // 管道写次数  
  
    if (access(FIFO, F_OK) == -1) {  
        // 测试有名管道FIFO是否存在,若不存在,则用mkfifo创建该管道  
        if ((mkfifo(FIFO, 0666) < 0) && (errno != EEXIST)) {  
            // 创建管道"myfifo",允许读写  
            perror("Can NOT create fifo file"); // 使用perror输出错误信息  
            exit(1);  
        }  
    }  

  
    if ((fd = open(FIFO, O_WRONLY)) == -1) {  
        // 调用open以只写方式打开FIFO,返回文件描述符fd  
        perror("Open fifo error"); // 使用perror输出错误信息  
        exit(1);  
    }  
  
    do {  
        printf("请输入要写入管道的内容(输入q退出):");  
        // 使用fgets代替gets,因为gets不安全,会造成缓冲区溢出  
        if (fgets(buff, BUFF_SIZE, stdin) != NULL) {  
            // 去除可能包含的换行符  
            buff[strcspn(buff, "\n")] = 0;  
  
            // 只写入用户输入的有效字符串长度,而不是整个缓冲区  
            if ((real_write = write(fd, buff, strlen(buff))) > 0) {  
                printf("第%d次写入管道: '%s'.\n", rw++, buff);  
            } else {  
                perror("Write to fifo error"); // 如果写入失败,打印错误信息  
                break;  
            }  
  
            // 如果用户输入了q,则退出循环  
            if (strcmp(buff, "q\n") == 0 || strcmp(buff, "q") == 0) {  
                break;  
            }  
        }  
    } while (strlen(buff) != 0);  
  
    close(fd);  
    exit(0);  
}

fifo_read.c

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <sys/types.h>  
#include <sys/stat.h>  
#include <fcntl.h>  
#include <unistd.h>  
#include <errno.h>  
  
#define FIFO "myfifo"  
#define BUFF_SIZE 1024  
  
int main() {  
    char buff[BUFF_SIZE];  
    ssize_t real_read; // 使用 ssize_t 而不是 int  
    int fd;  
    int rc = 1;  
  
    if (access(FIFO, F_OK) == -1) {  
        if ((mkfifo(FIFO, 0666) < 0) && (errno != EEXIST)) {  
            perror("Can NOT create fifo file");  
            exit(1);  
        }  
    }  
  
    if ((fd = open(FIFO, O_RDONLY)) == -1) {  
        perror("Open fifo error");  
        exit(1);  
    }  
  
    while (1) {  
        memset(buff, 0, BUFF_SIZE);  
        if ((real_read = read(fd, buff, BUFF_SIZE - 1)) > 0) { // 减1留给字符串结束符  
            buff[real_read] = '\0'; // 添加字符串结束符  
            printf("第%d次读取管道: '%s'.\n", rc++, buff);  
        } else if (real_read == 0) {  
            // 读取到EOF,这通常不会在有名管道中发生,但可以用于普通文件  
            break;  
        } else if (errno == EINTR) {  
            // 如果读取被中断(例如,由于信号),则重试  
            continue;  
        } else {  
            // 发生错误  
            perror("Read from fifo error");  
            break;  
        }  
    }  
  
    close(fd);  
    exit(0);  
}

编译链接命令:gcc fifo_write.c -o fifo_write

gcc fifo_read.c -o fifo_read

运行命令:./fifo_write

./fifo_read

注意:需要两个终端分别运行

交互与结果:

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值