Linux进程间通信的方式:
管道、信号
消息队列、共享内存、信号灯
套接字
1.管道:
1.无名管道
只能用于具有亲缘关系的进程间通信
无名管道创建后,进程会获得操作管道的两个文件描述符,创建子进程时,子进程会拷贝得到父进程的操作无名管道的两个文件描述符,
两个进程任务操作同一管道实现通信。
int pipe(int pipefd[2]);
功能:
创建一个用来通信的管道
参数:
pipefd:存放管道两端(读写)的文件描述符数组
成功返回0
失败返回-1
1.如果管道中至少有一个写端:
如果管道中有数据,直接读出
如果管道中没有数据,会阻塞等待直到有数据写入后读出
2.如果管道中没有写端:
如果管道中有数据,直接读出
如果管道中没有数据,不会阻塞直接继续向下执行
3.如果管道中至少有一个读端:
如果管道没有写满,直接写入
如果管道中写满(64k),则阻塞等待,等有数据读出才能继续写入
4.如果管道中没有读端:
向管道中写入数据会产生管道破裂信号
2.有名管道
通过管道在文件系统中的路径找到管道名,两个进程以读写的方式打开同一管道完成通信
mkfifo:
int mkfifo(const char *pathname, mode_t mode);
功能:
创建一个管道
参数:
pathname:管道文件的路径
mode:权限
返回值:
成功返回0
失败返回-1
有名管道必须读写两端同时加入后,才能继续向下执行
objectivec
#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
循环此过程实现两个进程聊天的功能