1.管道:
1.无名管道
只能用于具有亲缘关系的进程间通信
无名管道创建后,进程会获得操作管道的两个文件描述符,创建子进程时,子进程会拷贝得到父进程的操作无名管道的两个文件描述符,
两个进程任务操作同一管道实现通信。
int pipe(int pipefd[2]);
功能:
创建一个用来通信的管道
参数:
pipefd:存放管道两端(读写)的文件描述符数组
成功返回0
失败返回-1
1.如果管道中至少有一个写端:
如果管道中有数据,直接读出
如果管道中没有数据,会阻塞等待直到有数据写入后读出
2.如果管道中没有写端:
如果管道中有数据,直接读出
如果管道中没有数据,不会阻塞直接继续向下执行
3.如果管道中至少有一个读端:
如果管道没有写满,直接写入
如果管道中写满(64k),则阻塞等待,等有数据读出才能继续写入
4.如果管道中没有读端:
向管道中写入数据会产生管道破裂信号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | #include "../head.h" char tmpbuff[4096] = {0}; int main(void) { pid_t pid; int pipefd[2]; ssize_t nsize = 0; pipe(pipefd); pid = fork(); if (-1 == pid) { perror("fail to fork"); return -1; } if (0 == pid) { close(pipefd[0]); #if 0 strcpy(tmpbuff, "hello world"); write(pipefd[1], tmpbuff, strlen(tmpbuff)); read(pipefd[0], tmpbuff, sizeof(tmpbuff)); #endif while (1) { } } else if (pid > 0) { int cnt = 0; sleep(2); close(pipefd[0]); while (1) { printf("write前!\n"); write(pipefd[1], tmpbuff, sizeof(tmpbuff)); printf("write后!\n"); cnt++; printf("cnt = %d\n", cnt); } #if 0 nsize = read(pipefd[0], tmpbuff, sizeof(tmpbuff)); printf("读到 %ld 个字节,内容为: %s\n", nsize, tmpbuff); #endif } return 0; } |
2.有名管道
通过管道在文件系统中的路径找到管道名,两个进程以读写的方式打开同一管道完成通信
mkfifo:
int mkfifo(const char *pathname, mode_t mode);
功能:
创建一个管道
参数:
pathname:管道文件的路径
mode:权限
返回值:
成功返回0
失败返回-1
有名管道必须读写两端同时加入后,才能继续向下执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | #include "../head.h" extern int errno; int main(int argc, const char *argv[]) { int ret = 0; int fd = 0; char commandbuf[256] = {0}; if (argc < 2) { fprintf(stderr, "Usage:./a.out command arg\n"); return -1; } ret = mkfifo("/tmp/myfifo", 0664); if (-1 == ret && errno != EEXIST) { perror("fail to mkfifo"); return -1; } fd = open("/tmp/myfifo", O_RDWR); if (-1 == fd) { perror("fail to open"); return -1; } sprintf(commandbuf, "%s %s\n", argv[1], argv[2]); write(fd, commandbuf, strlen(commandbuf)); close(fd); return 0; } |
2.安装mplayer软件:
1.让Ubuntu可以上网
ping www.baidu.com
2.配置apt-get工具集的源
3.安装mplayer
sudo apt-get install mplayer
4.将视频拷贝到虚拟机中
mplayer 视频文件名
5.播放视频
mplayer -slave -input file=/tmp/myfifo 视频路径
4.编写两个进程任务clienta.c和clientb.c, clienta.c从终端接收一行字符串,通过管道发送给clientb.c
clientb.c接收到内容后打印,并从终端接收一行字符串,发回给clienta.c
循环此过程实现两个进程聊天的功能