Chinaunix首页 | 论坛 | 博客
  • 博客访问: 831246
  • 博文数量: 97
  • 博客积分: 3042
  • 博客等级: 中校
  • 技术积分: 1610
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-21 11:48
文章存档

2015年(1)

2014年(3)

2013年(4)

2012年(43)

2011年(44)

2010年(2)

分类: LINUX

2011-06-17 21:41:00

管道学习有一段时间了, 感觉自己应该把这段时间的学习点滴记录下来, 下面就结合几道编程题将所学知识串接一下:

题目1:通过管道进行的父/子进程通信
涉及主要知识点:未命名管道

/*
**熟悉: 
**     (1)read, write, fork 以及一些进程的东西
**该程序主要练习具有亲缘关系间进程的通信过程, 即无名管道, 通过该练习, 可知管道通信的步骤:
**     (1)创建管道.
**     (2)创建子进程.
**     (3)关闭不必要的读写端.
**     (4)按照需要进行读写数据.
**     (5)退出.
*/

#include
#include
#define MAXLINE 255

int main()
{
int pipe1[2];
int n;
char line[MAXLINE];
pid_t pid;

if(pipe(pipe1) < 0){
printf("创建管道失败!\n");
return -1;
}

if((pid = fork()) < 0) {
printf("创建子进程失败\n");
return -1;
}else if(pid > 0) {
close(pipe1[0]);
write(pipe1[1], "你好! 我是父进程!\n", 50);
}else{
// sleep(1);
close(pipe1[1]);
n = read(pipe1[0], line, MAXLINE);
write(NULL, line, n); //写至标准输出
}

// printf("\n");
return 0;
}


题目:使用两个个管道进程全双工通信:父进程从管道接收数据,然后将数据显示,再给子进程发送一个数据;子进程从管道接收数据,然后将数据显示,再给父进程发送一个数据。
/*
**该程序主要练习利用无名管道实现全双工通信, 不关闭相应端
*/
#include
#include
#include
#define MAXLINE 50

int main()
{
int pipe1[2], n;
char line[MAXLINE];
pid_t pid;

if(pipe(pipe1) < 0){
printf("创建管道失败!\n");
return -1;
}

if((pid = fork()) <0){
printf("创建子进程失败!\n");
return -1;
} else if(pid == 0) {

n = read(pipe1[0], line, MAXLINE);
printf("子进程读到的数据: %s\n", line);
sleep(1);
write(pipe1[1], "你好! 我是子进程!", 50 );
exit(0);
}else{
write(pipe1[1], "你好!我是父进程!", 50);

//sleep(1);
n = read(pipe1[0], line, MAXLINE);
printf("父进程读到的数据:%s\n", line);

exit(0);
}

return 0;
}



通过管道模拟shell命令:cat file | sort
涉及主要知识点:未命名管道、重定向
/*
** popen 在调用进程与管道之间建立一条管道,
**返回一个FILE的指针, 该指针或者用于输入或者用于输出
*/
#include
#include
#include
#include
#include
#define MAXLINE 50

int main()
{
int n, len;
char line[MAXLINE], command[MAXLINE], command1[MAXLINE];
FILE *fp, *fp1;

fgets(line, MAXLINE, stdin);
len = strlen(line);
if(line[len-1] == '\n'){
len--;
}

snprintf(command, sizeof(command), "cat %s", line);
fp = popen(command, "r");

snprintf(command1, sizeof(command1), "sort %s", line);
fp1 = popen(command1, "r");

printf("sort前的数据是:\n");
while(fgets(line, MAXLINE, fp) != NULL) {
// snprintf(command1, sizeof(command1), "sort %s", line);
// fp1 = popen(command1, "r");
fputs(line, stdout);
}

printf("sort后的数据是:\n");
while(fgets(line, MAXLINE, fp1) != NULL) {
fputs(line, stdout);
}

pclose(fp);
pclose(fp1);
exit(0);
}


题目3:命名管道(FIFO)实现客户-服务器关系。
/*
** 了解客户-服务器模型通信的思想, 掌握snprintf的用法
*/
#include
#include
#include
#include
#include
#include
#define MAXLINE 50

void client(int rd, int wd)
{
int n;
int len;
char line[MAXLINE];

printf("请输入:\n");
fgets(line, MAXLINE, stdin);
len = strlen(line);
if(line[len-1] == '\n'){
len--;
}


printf("line的内容是: %s\n", line);
write(wd, line, len);
printf("已写入!\n");
// sleep(2);
while((n = read(rd, line, MAXLINE)) > 0){
write(STDOUT_FILENO, line, n);
}
printf("客户端结束\n");
}

void server(int rd, int wd)
{
int n;
int len;
int fd;
char line[MAXLINE];


if((n = read(rd, line, MAXLINE)) < 0) {
printf("服务器读管道出错!\n");
exit(0);
}
printf("开始打开:\n");
printf("%s\n", line);
if((fd = open(line, O_RDONLY)) < 0) {
snprintf(line+n, sizeof(line)-n , ":can not open, %s\n", strerror(errno));
printf("服务器打开文件错误!\n");
n = strlen(line);
write(wd, line, n);
} else {
while((n = read(fd, line, MAXLINE)) > 0) {
write(wd, line, n);
}
close(fd);
}

}


int main()
{
int pipe1[2], pipe2[2];
pid_t pid;
int fd;

if(pipe(pipe1) < 0) {
printf("创建管道1失败!\n");
return -1;
}

if(pipe(pipe2) < 0) {
printf("创建管道2失败!\n");
return -1;
}

if((pid = fork()) < 0) {
printf("创建子进程失败!\n");
return -1;
}else if(pid > 0) {
close(pipe1[0]);
close(pipe2[1]);

client(pipe2[0], pipe1[1]);
exit(0);
} else {
sleep(2);
close(pipe1[1]);
close(pipe2[0]);

server(pipe1[0], pipe2[1]);
waitpid(pid , NULL, 0);
exit(0);
}

printf("\n");
return 0;
}
阅读(1106) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~