linux内核情景分析之命名管道
管道是一种"无名","无形文件,只可以近亲进程使用,不可以再任意两个进程通信使用,所以只能实现"有名","有形"的文件来实现就可以克服其缺点,这里的有名:一个文件应该有文件名,使得任何进程可以通过文件名或者路径找到该文件,有形指的是文件的inode应该存在与磁盘或者其他文件熊截止上.使得任何进程可以再任何时间都可以建立联系.
if (inode->i_ino == EXT2_ACL_IDX_INO ||inode->i_ino == EXT2_ACL_DATA_INO)/* Nothing to do */ ;else if (S_ISREG(inode->i_mode)) {inode->i_op = &ext2_file_inode_operations;inode->i_fop = &ext2_file_operations;inode->i_mapping->a_ops = &ext2_aops;} else if (S_ISDIR(inode->i_mode)) {inode->i_op = &ext2_dir_inode_operations;inode->i_fop = &ext2_dir_operations;} else if (S_ISLNK(inode->i_mode)) {if (!inode->i_blocks)inode->i_op = &ext2_fast_symlink_inode_operations;else {inode->i_op = &page_symlink_inode_operations;inode->i_mapping->a_ops = &ext2_aops;}} elseinit_special_inode(inode, inode->i_mode,le32_to_cpu(raw_inode->i_block[0]));
void init_special_inode(struct inode *inode, umode_t mode, int rdev){inode->i_mode = mode;if (S_ISCHR(mode)) {inode->i_fop = &def_chr_fops;inode->i_rdev = to_kdev_t(rdev);} else if (S_ISBLK(mode)) {inode->i_fop = &def_blk_fops;inode->i_rdev = to_kdev_t(rdev);inode->i_bdev = bdget(rdev);} else if (S_ISFIFO(mode))//是fifo文件,设置文件操作为def_fifo_fopsinode->i_fop = &def_fifo_fops;else if (S_ISSOCK(mode))inode->i_fop = &bad_sock_fops;elseprintk(KERN_DEBUG "init_special_inode: bogus imode (%o)\n", mode);}
/** Dummy default file-operations: the only thing this does* is contain the open that then fills in the correct operations* depending on the access mode of the file...*/struct file_operations def_fifo_fops = {open: fifo_open, /* will set read or write pipe_fops */};
static int fifo_open(struct inode *inode, struct file *filp){int ret;ret = -ERESTARTSYS;lock_kernel();if (down_interruptible(PIPE_SEM(*inode)))goto err_nolock_nocleanup;if (!inode->i_pipe) {//第一次打开fifo文件,该管道的缓冲页面没分配,以后打开会跳过ret = -ENOMEM;if(!pipe_new(inode))goto err_nocleanup;}filp->f_version = 0;switch (filp->f_mode) {case 1:/* //只读* O_RDONLY* POSIX.1 says that O_NONBLOCK means return with the FIFO* opened, even when there is no process writing the FIFO.*/filp->f_op = &read_fifo_fops;PIPE_RCOUNTER(*inode)++;//读端的记录++if (PIPE_READERS(*inode)++ == 0)//表示刚打开读端,很可能有写进程睡眠,那就要唤醒写进程wake_up_partner(inode);if (!PIPE_WRITERS(*inode)) {//如果不存在写端if ((filp->f_flags & O_NONBLOCK)) {//并且不阻塞/* suppress POLLHUP until we have* seen a writer */filp->f_version = PIPE_WCOUNTER(*inode);//写端计数} else //不存在写端并且阻塞,那就之产生一般,需要睡眠,等待生产者进程将其唤醒{wait_for_partner(inode, &PIPE_WCOUNTER(*inode));if(signal_pending(current))goto err_rd;}}break;case 2:/*只写* O_WRONLY* POSIX.1 says that O_NONBLOCK means return -1 with* errno=ENXIO when there is no process reading the FIFO.*///不存在读端并且设置了不阻塞,直接return错误ret = -ENXIO;if ((filp->f_flags & O_NONBLOCK) && !PIPE_READERS(*inode))goto err;filp->f_op = &write_fifo_fops;//设置专用写操作PIPE_WCOUNTER(*inode)++;if (!PIPE_WRITERS(*inode)++)//如果写端第一次创建,很可能有读进程在睡眠wake_up_partner(inode);//将其唤醒if (!PIPE_READERS(*inode)) {//如果不存在读端并且阻塞wait_for_partner(inode, &PIPE_RCOUNTER(*inode));//休眠等待读进程将其唤醒if (signal_pending(current))goto err_wr;}break;case 3:/*可读可写* O_RDWR* POSIX.1 leaves this case "undefined" when O_NONBLOCK is set.* This implementation will NEVER block on a O_RDWR open, since* the process can at least talk to itself.*///相当于一个进程同时打开命名管道的两端,所以不需要等待,只要任何一端是第一次打开,就唤醒在睡眠的进程filp->f_op = &rdwr_fifo_fops;PIPE_READERS(*inode)++;PIPE_WRITERS(*inode)++;PIPE_RCOUNTER(*inode)++;PIPE_WCOUNTER(*inode)++;if (PIPE_READERS(*inode) == 1 || PIPE_WRITERS(*inode) == 1)wake_up_partner(inode);break;default:ret = -EINVAL;goto err;}/* Ok! */up(PIPE_SEM(*inode));unlock_kernel();return 0;err_rd:if (!--PIPE_READERS(*inode))wake_up_interruptible(PIPE_WAIT(*inode));ret = -ERESTARTSYS;goto err;err_wr:if (!--PIPE_WRITERS(*inode))wake_up_interruptible(PIPE_WAIT(*inode));ret = -ERESTARTSYS;goto err;err:if (!PIPE_READERS(*inode) && !PIPE_WRITERS(*inode)) {struct pipe_inode_info *info = inode->i_pipe;inode->i_pipe = NULL;free_page((unsigned long)info->base);kfree(info);}err_nocleanup:up(PIPE_SEM(*inode));err_nolock_nocleanup:unlock_kernel();return ret;}
linux内核情景分析之命名管道的更多相关文章
- linux内核情景分析之匿名管道
管道的机制由pipe()创建,由pipe()所建立的管道两端都在同一进程.所以必须在fork的配合下,才可以在具有亲缘关系的进程通信 /* * sys_pipe() is the normal C c ...
- linux内核情景分析之execve()
用来描述用户态的cpu寄存器在内核栈中保存情况.可以获取用户空间的信息 struct pt_regs { long ebx; //可执行文件路径的指针(regs.ebx中 long ecx; //命令 ...
- Linux内核情景分析之消息队列
早期的Unix通信只有管道与信号,管道的缺点: 所载送的信息是无格式的字节流,不知道分界线在哪,也没通信规范,另外缺乏控制手段,比如保温优先级,管道机制的大小只有1页,管道很容易写满而读取没有及时,发 ...
- Linux内核情景分析的alloc_pages
NUMA结构的alloc_pages ==================== mm/numa.c 43 43 ==================== 43 #ifdef CONFIG_DISCON ...
- Linux内核情景分析之异常访问,用户堆栈的扩展
情景假设: 在堆内存中申请了一块内存,然后释放掉该内存,然后再去访问这块内存.也就是所说的野指针访问. 当cpu产生页面错误时,会把失败的线性地址放在cr2寄存器.线性地址缺页异常的4种情况 1.如果 ...
- linux内核情景分析之exit与Wait
//第一层系统调用 asmlinkage long sys_exit(int error_code) { do_exit((error_code&0xff)<<8); } 其主体是 ...
- linux内核情景分析之内核中的互斥操作
信号量机制: struct sempahore是其结构,定义如下 struct semaphore { atomic_t count;//资源数目 int sleepers;//等待进程数目 wait ...
- linux内核情景分析之信号实现
信号在进程间通信是异步的,每个进程的task_struct结构有一个sig指针,指向一个signal_struct结构 定义如下 struct signal_struct { atomic_t cou ...
- linux内核情景分析之强制性调度
从系统调用返回到用户空间是否调度,从ret_with_reschedule可看出,是否真正调度,取决于当前进程的pcb中的need_resched是否设置为1,那如何设置为1取决于以下几种情况: 时间 ...
随机推荐
- Tomcat之web.xml中的<url-pattern>标签
关于web.xml配置中的<url-pattern> 标签<url-pattern> <url-pattern>是我们用Servlet做Web项目时需要经常配置的标 ...
- luogu3375 【模板】KMP字符串匹配
nxt数组下标从1开始而a,b数组下标从0开始. #include <iostream> #include <cstring> #include <cstdio> ...
- python2.X中文乱码
在IDE下,加上# -- coding: UTF-8 -- 并且保证IDE也是utf-8编码. 在CMD下,这样执行会有乱码,为啥呢,因为cmd下是gbk编码的,你写的代码必须也是gbk编码的,你可以 ...
- Leetcode 599.两个列表的最小索引总和
两个列表的最小索引总和 假设Andy和Doris想在晚餐时选择一家餐厅,并且他们都有一个表示最喜爱餐厅的列表,每个餐厅的名字用字符串表示. 你需要帮助他们用最少的索引和找出他们共同喜爱的餐厅. 如果答 ...
- springmvc和struts2的区别比较
1.Struts2是类级别的拦截, 一个类对应一个request上下文,SpringMVC是方法级别的拦截,一个方法对应一个request上下文,而方法同时又跟一个url对应,所以说从架构本身上Spr ...
- python 中输入一个字符串,判断这个字符串中有多少个字符、数字、空格、特殊字符
# -*- coding: utf8 -*- # Author:wxq #python 2.7 #首先定义一个字符串 str1 = raw_input('请输入一个字符:') #初始化字符.数字.空格 ...
- File IO(NIO.2):什么是路径?
简介 文件系统以某种形式的媒体(通常为一个或多个硬盘驱动器)存储和组织文件,使得它们可以容易地被检索.目前使用的大多数文件系统将文件存储在树形(或分层)结构中.在树的顶部是一个(或多个)根节点.在根节 ...
- PIC单片机之时钟设置
PIC单片机之时钟设置 http://blog.csdn.net/superanters/article/details/8541650 内部时钟和外部时钟? PIC单片机有许多型号可以设置成 用外部 ...
- POJ 2763 Housewife Wind(DFS序+LCA+树状数组)
Housewife Wind Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 11419 Accepted: 3140 D ...
- linux系统初始化——启动脚本是如何工作的
启动脚本是如何工作的 Linux 使用的是基于 运行级(run-levels) 概念的称为 SysVinit 的专用启动工具.它在不同的系统上可能是完全不一样的,所以不能认为一个脚本在某个 Linux ...