进程间通信

进程间通信有五种方式:
第一种没学
第二种匿名管道

截取自linux0.11内核源码中的pipe系统调用

int sys_pipe(unsigned long * fildes)
{
	struct m_inode * inode;
	struct file * f[2];
	int fd[2];
	int i,j;

	j=0;
	for(i=0;j<2 && i<NR_FILE;i++)
		if (!file_table[i].f_count)
			(f[j++]=i+file_table)->f_count++;
	/*上面那一段是在内核filetable中找出空闲的,然后将其计数加一,表示已被占用*/
	if (j==1)
		f[0]->f_count=0;
	if (j<2)
		return -1;
	j=0;
	/*如果没有找到两个就进行清除并返回-1*/
	for(i=0;j<2 && i<NR_OPEN;i++)
		if (!current->filp[i]) {
			current->filp[ fd[j]=i ] = f[j];
			j++;
		}
	/*从当前进程找两个空闲的file并将其指向内核的filetable*/
	if (j==1)
		current->filp[fd[0]]=NULL;
	if (j<2) {
		f[0]->f_count=f[1]->f_count=0;
		return -1;
	}
	/*struct m_inode * get_pipe_inode(void)
{
	struct m_inode * inode;

	if (!(inode = get_empty_inode()))
		return NULL;
	if (!(inode->i_size=get_free_page())) {
		inode->i_count = 0;
		return NULL;
	}
	inode->i_count = 2;	
	PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
	///#define PIPE_HEAD(inode) ((inode).i_zone[0])
	//#define PIPE_TAIL(inode) ((inode).i_zone[1])
	inode->i_pipe = 1;
	return inode;
	***找一个空闲的inode,并对inode进行设置,我对inode也不是很了解,以后再进行补充***
}
*/
	if (!(inode=get_pipe_inode())) {
		current->filp[fd[0]] =
			current->filp[fd[1]] = NULL;
		f[0]->f_count = f[1]->f_count = 0;
		return -1;
	}
	f[0]->f_inode = f[1]->f_inode = inode;
	f[0]->f_pos = f[1]->f_pos = 0;
	f[0]->f_mode = 1;		/* read */
	f[1]->f_mode = 2;		/* write */
	/*extern inline void put_fs_long(unsigned long val, unsigned long *addr);
extern inline 表示该函数是一个外部链接的内联函数,内联函数可以在调用点直接展开,而不需要像普通函数那样进行函数调用的开销。
内联汇编代码:

__asm__ ("movl %0,%%fs:%1"::"r" (val),"m" (*addr));
__asm__ 是 GCC 和其他兼容的编译器用来嵌入汇编语言代码的关键字。
"movl %0,%%fs:%1" 是汇编指令,将 %0 寄存器中的值移动到 %fs 段寄存器偏移地址为 %1 处的内存位置。
%0 对应于 "r" (val),表示使用寄存器约束,将 val 的值加载到 %0 中。
%%fs:%1 对应于 "m" (*addr),表示将 addr 指针所指向的内存地址作为内存约束,即将 %0 中的值写入到 %fs 段寄存器的偏移地址为 %1 处的内存位置。*/
	put_fs_long(fd[0],0+fildes);
	put_fs_long(fd[1],1+fildes);
	return 0;
}

看完上面代码,不太理解在使用管道时,将传输的信息保存在哪(就是内核的filetable不对应具体的文件,你在使用管道时,read和write的数据保存在哪),所以研究一下inode,还要分析read和write。
inode可以看linux文件系统综述
linux文件目录代码解析
在这里插入图片描述
目录也是一个文件,找到目录的i节点,读出对应的数据区的数据,数据是下一层目录的i节点的地址和对应的文件名字,这样一层层的套下去,直到找到匹配的文件。

第三种:有名管道
把匿名管道的内核文件结构体换成了具体的文件,这样你就可以不需要父子进程都可以访问这个文件。
**mkfifo的用法**
第四种 共享内存
分三步
在这里插入图片描述
shmopen
在这里插入图片描述
在这里插入图片描述

3.mmap();
mmap主要用来做内存映射的,可以将虚拟内存和磁盘上的文件直接映射。正常来说我们在写文件读文件的时候是需要使用系统调用api来进行,比如说read/write,这两个系统调用读写文件的方式是需要进行两次拷贝的,从用户空间拷贝到内核空间,然后从内核空间再拷贝到磁盘,而mmap将文件的地址直接映射到虚拟内存,这样,我们直接往这个地址读/写内容,可以像操作malloc申请出来的空间地址一样,写到这个地址,内容就直接在文件中了,减少了一次拷贝,提高了效率。这样一个公共的内存区域,也可以用来进程间通信
具体可以参考mmap()
第五种消息队列

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值