一.引言
在同一台计算机中的进程相互通信的方式主要有:管道(pipe)、信号(Signal)、信号量(Semaphore)、消息队列(Message)、共享内存(shared memory),其中信号量、消息队列、共享内存被称为IPC机制。Posix system v fork() CreateProcess CreateThread pthread_create()
不同机器之间的进程通讯可以使用套接字技术。SOCKET
1.管道(匿名管道)
管道是IPC机制中的最老形式,是进程直接进行数据交换得通道,并且所有UNIX系统都提供了此种通信机制,管道分为普通管道和命名管道,他们都是通过内核缓冲区按先进先出得方式进行数据传输,其普通管道的特点为:
半双工
只能在具有公共祖先的进程之间使用
单独构成一种独立的文件系统
没有名字
管道的缓冲区是有限的
管道说传送的数据是无格式的
写入管道的数据读完之后就从管道中消失
2.管道的创建与读写
(1)无名管道
创建管道:Int pipe(int fd[2]);
fd[0]读出数据
fd[1]写入数据
(2)命名管道
创建管道:int mkfifo(const char *pathname, mode_t mode);
一般文件的I/O操作函数都可以用于管道。
close(fd)
int read(fd, buffer, len)
int write(fd, buffer, len)
二.匿名管道代码演示
利用匿名管道实现剧本化的对话
/*用无名管道进行通信
*采取剧本的方式
*2017-3-6
* */
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<sys/wait.h>
#include<time.h>
#define MAX_MSG_SIZE 256
int main()
{
char* parent_talk[] = {"hello", "what is the time?", "ok, bye", NULL};
char* child_talk[] = {"hi", "time is ", "bye", NULL};
int fd1[2];
int fd2[2];
int res = pipe(fd1);
if(res == -1)
{
perror("pipe");
exit(EXIT_FAILURE);
}
res = pipe(fd2);
if(res == -1)
{
perror("pipe");
exit(EXIT_FAILURE);
}
pid_t pid = fork();
if(pid == 0)//child
{
close(fd1[1]);
close(fd2[0]);
char buf[MAX_MSG_SIZE];
int i = 0;
char *talk = child_talk[i];
while(talk != NULL)
{
read(fd1[0], buf, MAX_MSG_SIZE);
printf("parent say:>%s\n", buf);
write(fd2[1], talk, strlen(talk)+1);
i++;
talk = child_talk[i];
}
close(fd1[0]);
close(fd2[1]);
}
else if(pid > 0)//parent
{
close(fd1[0]);
close(fd2[1]);
char buf[MAX_MSG_SIZE];
int i = 0;
char *talk = parent_talk[i];
while(talk != NULL)
{
write(fd1[1], talk, strlen(talk)+1);
read(fd2[0], buf, MAX_MSG_SIZE);
if(strcmp(buf, child_talk[1]) == 0)
{
time_t timep;
struct tm *p;
time(&timep);;
strcat(buf, ctime(&timep));
}
printf("child :>%s\n", buf);
i++;
talk = parent_talk[i];
}
close(fd1[1]);
close(fd2[0]);
int stat;
wait(&stat);
}
else
{
perror("fork");
exit(EXIT_FAILURE);
}
return 0;
}
测试结果
利用匿名管道实现正常的对话
/*匿名管道通信
*采取对话的形式
* 2017-3-6
* */
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<string.h>
#define MAX_MSG_SIZE 256
int main()
{
int fd1[2];
int fd2[2];
int res = pipe(fd1);
if(res == -1)
{
perror("pipe");
exit(EXIT_FAILURE);
}
res = pipe(fd2);
if(res == -1)
{
perror("pipe");
exit(EXIT_FAILURE);
}
pid_t pid;
pid = fork();
if(pid == 0) //child process
{
char sendbuffer[MAX_MSG_SIZE] = {'\0'};
char recbuffer[MAX_MSG_SIZE] = {'\0'};
close(fd1[1]);
close(fd2[0]);
while(1)
{
read(fd1[0], recbuffer, MAX_MSG_SIZE);
printf("parent(by child):>%s\n", recbuffer);
printf("child say (by child):>");
scanf("%s", &sendbuffer);
if(strcmp(sendbuffer, "quit") == 0)
break;
write(fd2[1], sendbuffer, strlen(sendbuffer)+1);
}
close(fd1[0]);
close(fd2[1]);
}
else if(pid > 0)//parent process
{
char sendbuffer[MAX_MSG_SIZE] = {'\0'};
char recbuffer[MAX_MSG_SIZE] = {'\0'};
close(fd1[0]);
close(fd2[1]);
while(1)
{
printf("parent say (by parent):>");
scanf("%s", &sendbuffer);
if(strcmp(sendbuffer, "quit") == 0)
break;
write(fd1[1], sendbuffer, strlen(sendbuffer)+1);
read(fd2[0], recbuffer, MAX_MSG_SIZE);
printf("child(by parent):>%s\n", recbuffer);
}
close(fd1[1]);
close(fd2[0]);
int stat;
wait(&stat);
}
else
{
perror("fork child process");
exit(EXIT_FAILURE);
}
}
测试结果