Linux系统进程间通信:标准流管道popen和pclose函数

popen简介:

Linux系统提供了两个标准流管道的操作函数popen和pclose。这两个函数实现的操作是:
创建一个管道,fork一个子进程,关闭管道的不使用端,通过exec函数执行一个shell命令,等待命令终止。

popen函数声明:

#include <stdio.h>

FILE *popen(const char *command,const char *type);

功能:popen打开的数据管道流,pclose关闭数据管道流。popen必须由pclose来关闭。

参数说明:

command:shell 命令字符串的指针。

type:用来表示读("r")或者写("w")的,如果type是"r",则返回的文件指针是可读的,如果type是"w",则是可写的。不能同时为读和写。

返回值:返回:若成功则为文件指针,若出错则为NULL。

popen函数使用举例:

模拟一个shell命令的实现,将命令结果保存到已有文件中。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

/*将命令行执行的结果保存到一个已经存在的文件中 */ 
int main(int argc, char* argv[])
{
    
    FILE *pipe_fp;
    FILE *infile;

    //pid_t pid;
    char buffer[80];

    if (argc != 3) {
        fprintf(stderr, "usage: popen3[commond][filename]\n");
        exit(1);
    }
    if ((infile = fopen(argv[2],"wt")) == NULL) {
        perror("fopen");
        exit(1);
    }

    if ((pipe_fp = popen(argv[1],"r")) == NULL) {
        perror("popen");
        exit(1);
    }

    while (fgets(buffer, sizeof(buffer), pipe_fp) != NULL) {
        // if (tmp[strlen(tmp) - 1] == '\n') {
        //     tmp[strlen(tmp) - 1] = '\0'; //去除换行符
        // }
        fputs(buffer,infile);
    }

    // do {
    //     fgets(buffer,80,pipe_fp);
    //     // if (feof(infile)) {
    //     //     break;
    //     // }
    //     fputs(buffer,infile);
    // } while(!feof(infile));
    fclose(infile);
    pclose(pipe_fp);

    return(0);
}

程序使用方法:

输入三个字符串,第一个是编译好的可执行程序;第二个是shell可以识别的命令;第三个是已经存在的文件。

运行结果:

 myls ls in.txt

其中,myls就是上面的代码编译出来的可执行文件。这样,就把shell命令ls的结果保存在in.txt中了。(注意,必须先创建一个in.txt文件,这是为了简化程序)。

popen函数的源代码(来自于Android):

在Android系统中,我们可以查找到这样一个文件popen.c,文件位置和代码:

bionic/libc/unistd/popen.c:

/*	$OpenBSD: popen.c,v 1.17 2005/08/08 08:05:34 espie Exp $ */
/*
 * Copyright (c) 1988, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software written by Ken Arnold and
 * published in UNIX Review, Vol. 6, No. 8.
 *
 *......//省略若干
 */

#include <sys/param.h>
#include <sys/wait.h>

#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <paths.h>

static struct pid {
	struct pid *next;
	FILE *fp;
	pid_t pid;
} *pidlist;

extern char **environ;

FILE *
popen(const char *program, const char *type)
{
	struct pid * volatile cur;
	FILE *iop;
	int pdes[2];
	pid_t pid;
	char *argp[] = {"sh", "-c", NULL, NULL};

	if ((*type != 'r' && *type != 'w') || type[1] != '\0') {
		errno = EINVAL;
		return (NULL);
	}

	if ((cur = malloc(sizeof(struct pid))) == NULL)
		return (NULL);

	if (pipe(pdes) < 0) {
		free(cur);
		return (NULL);
	}

	switch (pid = fork()) {
	case -1:			/* Error. */
		(void)close(pdes[0]);
		(void)close(pdes[1]);
		free(cur);
		return (NULL);
		/* NOTREACHED */
	case 0:				/* Child. */
	    {
		struct pid *pcur;
		/*
		 * We fork()'d, we got our own copy of the list, no
		 * contention.
		 */
		for (pcur = pidlist; pcur; pcur = pcur->next)
			close(fileno(pcur->fp));

		if (*type == 'r') {
			(void) close(pdes[0]);
			if (pdes[1] != STDOUT_FILENO) {
				(void)dup2(pdes[1], STDOUT_FILENO);
				(void)close(pdes[1]);
			}
		} else {
			(void)close(pdes[1]);
			if (pdes[0] != STDIN_FILENO) {
				(void)dup2(pdes[0], STDIN_FILENO);
				(void)close(pdes[0]);
			}
		}
		argp[2] = (char *)program;
		execve(_PATH_BSHELL, argp, environ);
		_exit(127);
		/* NOTREACHED */
	    }
	}

	/* Parent; assume fdopen can't fail. */
	if (*type == 'r') {
		iop = fdopen(pdes[0], type);
		(void)close(pdes[1]);
	} else {
		iop = fdopen(pdes[1], type);
		(void)close(pdes[0]);
	}

	/* Link into list of file descriptors. */
	cur->fp = iop;
	cur->pid =  pid;
	cur->next = pidlist;
	pidlist = cur;

	return (iop);
}

/*
 * pclose --
 *	Pclose returns -1 if stream is not associated with a `popened' command,
 *	if already `pclosed', or waitpid returns an error.
 */
int
pclose(FILE *iop)
{
	struct pid *cur, *last;
	int pstat;
	pid_t pid;

	/* Find the appropriate file pointer. */
	for (last = NULL, cur = pidlist; cur; last = cur, cur = cur->next)
		if (cur->fp == iop)
			break;

	if (cur == NULL)
		return (-1);

	(void)fclose(iop);

	do {
		pid = waitpid(cur->pid, &pstat, 0);
	} while (pid == -1 && errno == EINTR);

	/* Remove the entry from the linked list. */
	if (last == NULL)
		pidlist = cur->next;
	else
		last->next = cur->next;
	free(cur);

	return (pid == -1 ? -1 : pstat);
}

 从代码路径可以看到,popen是在libc库中实现的,而且是通过调用pipe()函数创建的管道。

 


  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
本书通过55个精彩的实例,全面剖析了在Linux下编写网络应用程序的方法,并阐述了网络协议架构和开发规范。为了适应不同读者的需要,本书从最基本的Linux系统操作到网络技术的基本理念,逐步深入至Linux/UNIX下具体的编程实践,结合大量具体实例和编程经验,为读者展现Linux平台下网络编程的魅力。 全书由13章组成,内容涉及到Lindx系统编程基础、TCP/UDP协议、套接字编程概念及I/O模型、高级编程中需要用到的进程问通信同步、多路复用、多线程编程和一些高级套接字控制方法、IPv6介绍以及网络安全等。本书最后还汇集了很多网络编程的具体实例,读者可以模仿书中的范例来开发自己的应用程序。 本书内容丰富结构清晰,实例典型,文字简洁畅,边讲边练。不但是Linux应用与开发的从业人员的指导书,而且也可作为大专院校相关专业师生教学与自学的参考书以及社会初、中级培训班教材。 基础篇 第1章 linux平台环境简单回顾 1.1 文件系统及其操作 1.1.1 文件系统结构 1.1.2 文件i/o操作 1.1.3 文件、目录及操作 1.2 标推输入输出 1.2.1 和buffer 1.2.2 i/o类型 1.3 进程概念及控制 1.3.1 进程的运行和终止 1.3.2 进程间竞争 1.3.3 wait操作 1.4 信号 1.4.1 信号屏蔽字 1.4.2 相关操作 1.5 本章小结 第2章 进程间通信 2.1 管道和fif0 2.1.1 管道的创建和使用 .2.1.2 实例 2.1.3 popenpclose函数 2.1.4 fifo的创建和使用 2.1.5 用fif0实现多客户服务 2.1.6 系统管道和fif0的限制 2.2 消息队列 2.2.1 消息队列的数据结构 2.2.2 消息队列的创建 2.2.3 消息队列的操作 2.2.4 实例 2.2.5 消息队列的限制 2.3 信号量 2.3.1 信号量的数据结构 2.3.2 信号量的创建和操作 2.4 共享内存区 2.4.1 共享内存区的数据结构 2.4.2 共享内存区的创建和操作 2.4.3 实例 2.4.4 共享内存区的限制 2.5 本章小结 第3章 传输层协议tcp和udp 3.1 tcp/ip基本框架 3.1.1 网络协议与层次 3.1.2 数据的封装与分用 3.1.3 客户-服务器模型 3.2 用户数据报协议(udp) 3.2.1 udp首部 3.3 传输控制协议(tcp) 3.3.1 顺序传输 3.3.2 保证数据的可靠性与完整性 3.3.3 双向传输 3.3.4 tcp首部 3.4 tcp连接的建立、握手与结束 3.4.1 连接的建立--三方握手 3.4.2 tcp参数 3.4.3 tcp连接的终止 3.5 端口 3.5.1 端口号的分配 3.5.2 套接字对 3.6 缓冲区 3.7 标准internet服务 3.8 本章小结 第4章 tcp套接字简介 4.1 套接字概述 4.2 套接字地址结构 4.3 位顺序调整 4.3.1 字节处理函数 4.3.2 地址转换函数 4.4 建立套接字 4.5 连接 4.5.1 客户端 4.5.2 服务器端 4.6 服务进程创建 4.6.1 函数介绍 4.6.2 范例 4.7 终止连接 4.8 连接地址信息获取 4.9 socket编程client/server应用简单示例 4.9.1 一个简单www浏览器 4.9.2 inetd编程 4.9.3 获取本地ip 4.9.4 dns的使用 4.9.5 从socket中读出一行语句 4.9.6 处理用户登录及权限设置 4.10 本章小结 第5章 tcp套接字编程实例 5.1 tcp客户--服务器实例一 5.1.1 服务器端代码-vcserver.c 5.1.2 客户端代码-vcclient.c 5.1.3 运行结果 5.2 实例之二 5.2.1 服务器端代码-tcpserver.c 5.2.2 客户端代码-tcpclient.c 5.3 本章小结 第6章 udp数据报 6.1 udp通讯机制 6.1.1 基本通讯过程 6.1.2 udp与tcp的比较 6.1.3 连接的udp 6.1.4 udp应用实例 6.2 udp的应用场合 6.3 增加udp的可靠性 6.4 udp编程综合实例 6.5 本章小结 第7章 套接字中的i/o模型 7.1 阻塞式i/o 7.1.1 读阻塞 7.1.2 写阻塞 7.1.3 会接宁建立中的阻塞 7.1.4 实例一 7.1.5 实例二 7.2 非阻塞式i/o 7.2.1 读操作 7.2.2 写操作 7.2.3 建立连接过程 7.2.4 接收连接过程 7.2.5 非阻塞方式的实现 7.3 实例 7.3.1 taik实例 7.3.2 可处理并发服务的echo实例 第8章 套接字属性控制 8.1 获取和设置套接字属性 8.1.1 getsockopt函数和 setsockopt函数 8.1.2 通用套接字属性 8.2 ipv4和ipv6套接字属性 8.3 套接字属性控制 8.3.1 ioctl函数 8.3.2 fcntl函数 8.4 本章小结 提 高 篇 第9章 进程间通讯的同步 9.1 互斥锁 9.1.1 互斥锁的基本原理 9.1.2 互斥锁的基本操作函数 9.1.3 编程实例 9.2 条件变量 9.2.1 条件变量的基本过程 9.2.2 条件变量的操作函数 9.2.3 编程实例 9.3 读写锁 9.3.1 基本原理 9.3.2 读写锁的操作函数 9.4 记录上锁 9.4.1 记录上锁的基本原理 9.4.2 fcntl记录上锁 9.4.3 记录上锁应用举例 9.5 本章小结 第10章 多路复用和信号驱动i/0 10.1 多路复用 10.1.1 多路复用的基本原理 10.1.2 select函数 10.1.3 select应用实例 10.2 poll函数 10.3 多路复用编程实例 10.4 信号驱动i/0 10.5 本章小结 第11章 高级套接字i/0操作 11.1 send和recv函数 11.1.1 send函数 11.1.2 recv函数 11.2 readv和writev函数 11.2.1 readv函数 11.2.2 writev函数 11.3 sendto和recvfrom函数 11.3.1 sendto函数 11.3.2 recvfrom()函数 11.3.3 一个运用sendto()和recvfrom()函数的实例 11.4 recvmsg和sendmsg函数 11.5 辅助数据 11.6 本章小结 第12章 多线程编程及网络应用 12.1 基本概念 12.1.1 引入多线程的原因 12.1.2 线程的基本概念 12.1.3 线程的分类 12.2 线程基础 12.2.1 线程的基本操作函数 12.2.2 简单的多线程编程 12.2.3 修改线程的属性 12.3 线程应用中的同步问题 12.3.1 特定线程数据 12.3.2 互斥锁 12.3.3 条件变量 12.3.4 信号量 12.4 多线程编程的网络应用 12.4.1 函数的多线程安全性 12.4.2 多线程的实际应用 12.5 本章小结 第13章 ip协议及其属性 13.1 ipv4内容 13.1.1 ipv4数据报的格式 13.1.2 ipv4地址 13.1.3 ipv4选项 13.1.4 internet控制报文协议icmp 13.1.5 internet路由选择协议 13.1.6 ipv4的局限性及其缺点 13.2 ipv6内容 13.2.1 ipv6基本头部的格式 13.2.2 ipv4到ipv6的变化 13.2.3 ipv6地址 13.2.4 ipv6的扩展头部 13.2.5 ipv6路由选择 第14章 网络编程的安全性问题 14.1 系统子程序 14.1.1 i/0子程序 14.1.2 进程控制 14.1.3 文件属性 14.1.4 uid和gid的处理 14.2 标准c库 14.2.1 标准i/o 14.2.2 /etc/passwd处理 14.2.3 /etc/group的处理 14.2.4 加密子程序 14.2.5 运行shell 14.3 写安全的c程序 14.4 root程序的设计 14.5 本章小结 实例篇 实例一 ping 实例二 聊天室的实现 实例三 端口扫描程序 实例四 网页更新检查程序 实例五 sniffer的基本实现 实例六 ip包检查程序 实例七 ip欺骗实例 实例八 路由测试程序 实例九 linux防火墙的编写 实例十 守护进程 实例十一 普通文件传输协议(tftp) 附录 附录一 gcc命令选项 1.使用语法 2.选项 附录二 makefile文件的编写方法 1.makefile文件的基本结构 2.makefile文件编写规则 3.makefile变量 4.假象目的 5.函数 6.实用makefile举例 7.一个的功能齐全的makefile 附录三 gdb调试器 1.gdb的基本使用方法 2.gdb命令 3.在gdb下运行程序
UNIX环境高级编程_第2版 ----------------------------------------------------------- 共两个压缩包( UNIX环境高级编程_第2版.part1 UNIX环境高级编程_第2版.part1 ) ------------------------------------------------------------ 原书名: Advanced Programming in the UNIX Environment 原出版社: Addison-Wesley 作者: (美)W.Richard Stevens, Stephen A.Rago [作译者介绍] 译者: 尤晋元 张亚英 戚正伟 丛书名: 图灵程序设计丛书 操作系统 出版社:人民邮电出版社 ISBN:7115147310 上架时间:2006-5-17 出版日期:2006 年5月 开本:16开 页码:758 版次:2-1 内容简介 ----------------------------------------------------------- 本书是被誉为UNIX编程“圣经”的Advanced Programming in the UNIX Environment一书的第2版。在   本书第1版出版后的十几年中,UNIX行业已经有了巨大的变化,特别是影响UNIX编程接口的有关标准变   化很大。本书在保持了前一版风格的基础上,根据最新的标准对内容进行了修订和增补,反映了最新的技   术发展。书中除了介绍UNIX文件和目录、标准I/O库、系统数据文件和信息、进程环境、进程控制、进程   关系、信号、线程、线程控制、守护进程、各种I/O、进程间通信、网络IPC、伪终端等方面的内容,还在   此基础上介绍了多个应用实例,包括如何创建数据库函数库以及如何与网络打印机通信等。此外,还在附   录中给出了函数原型和部分习题的答案。   本书内容权威,概念清晰,阐述精辟,对于所有层次UNIX/Linux程序员都是一本不可或缺的参考书。 目录 ----------------------------------------------------------- 第1章unix基础知识1 1.1 引言1 1.2 unix体系结构1 1.3 登录1 1.4 文件和目录3 1.5 输入和输出6 1.6 程序和进程8 1.7 出错处理10 1.8 用户标识12 1.9 信号14 1.10 时间值15 1.11 系统调用和库函数16 1.12 小结17 习题18 第2章unix标准化及实现19 2.1 引言19 2.2 unix标准化19 2.2.1 iso c 19 2.2.2 ieee posix 20 2.2.3 single unix specification 25 .2.2.4 fips 26 2.3 unix系统实现26 2.3.1 svr4 26 2.3.2 4.4bsd 27 2.3.3 freebsd 27 2.3.4 linux 27 2.3.5 mac os x 28 2.3.6 solaris 28 2.3.7 其他unix系统28 2.4 标准和实现的关系28 2.5 限制29 2.5.1 iso c限制29 2.5.2 posix限制30 2.5.3 xsi限制32 2.5.4 sysconf、pathconf和fpathconf 函数32 2.5.5 不确定的运行时限制38 2.6 选项42 2.7 功能测试宏44 2.8 基本系统数据类型45 2.9 标准之间的冲突45 2.10 小结46 习题46 第3章文件i/o 47 3.1 引言47 3.2 文件描述符47 3.3 open函数48 3.4 creat函数49 3.5 close函数50 3.6 lseek函数50 3.7 read函数53 3.8 write函数54 3.9 i/o的效率54 3.10 文件共享56 3.11 原子操作59 3.12 dup和dup2函数60 3.13 sync、fsync和fdatasync函数61 3.14 fcntl函数62 3.15 ioctl函数66 3.16 /dev/fd 67 3.17 小结68 习题68 第4章文件和目录71 4.1 引言71 4.2 stat、fstat和lstat函数71 目录 4.3 文件类型72 4.4 设置用户id和设置组id 74 4.5 文件访问权限75 4.6 新文件和目录的所有权77 4.7 access函数77 4.8 umask函数79 4.9 chmod和fchmod函数81 4.10 粘住位83 4.11 chown、fchown和lchown函数84 4.12 文件长度85 4.13 文件截短86 4.14 文件系统86 4.15 link、unlink、remove和rename 函数89 4.16 符号链接91 4.17 symlink和readlink函数94 4.18 文件的时间94 4.19 utime函数95 4.20 mkdir和rmdir函数97 4.21 读目录98 4.22 chdir、fchdir和getcwd函数102 4.23 设备特殊文件104 4.24 文件访问权限位小结106 4.25 小结106 习题107 第5章标准i/o库109 5.1 引言109 5.2 和file对象109 5.3 标准输入、标准输出和标准出错110 5.4 缓冲110 5.5 打开112 5.6 读和写114 5.7 每次一行i/o 116 5.8 标准i/o的效率117 5.9 二进制i/o 119 5.10 定位120 5.11 格式化i/o 121 5.12 实现细节125 5.13 临时文件127 5.14 标准i/o的替代软件130 5.15 小结130 习题130 第6章系统数据文件和信息133 6.1 引言133 6.2 口令文件133 6.3 阴影口令136 6.4 组文件137 6.5 附加组id138 6.6 实现的区别139 6.7 其他数据文件139 6.8 登录账户记录140 6.9 系统标识141 6.10 时间和日期例程142 6.11 小结146 习题146 第7章进程环境147 7.1 引言147 7.2 main函数147 7.3 进程终止147 7.4 命令行参数151 7.5 环境表152 7.6 c程序的存储空间布局152 7.7 共享库154 7.8 存储器分配154 7.9 环境变量157 7.10 setjmp和longjmp函数159 7.11 getrlimit和setrlimit函数164 7.12 小结168 习题168 第8章进程控制171 8.1 引言171 8.2 进程标识符171 8.3 fork函数172 8.4 vfork函数176 8.5 exit函数178 8.6 wait和waitpid函数179 8.7 waitid函数183 8.8 wait3和wait4函数184 8.9 竞争条件185 8.10 exec函数188 2 目录 8.11 更改用户id和组id 192 8.12 解释器文件196 8.13 system函数200 8.14 进程会计203 8.15 用户标识208 8.16 进程时间208 8.17 小结210 习题211 第9章进程关系213 9.1 引言213 9.2 终端登录213 9.3 网络登录216 9.4 进程组218 9.5 会话219 9.6 控制终端220 9.7 tcgetpgrp、tcsetpgrp和tcgetsid 函数221 9.8 作业控制222 9.9 shell执行程序225 9.10 孤儿进程组228 9.11 freebsd实现230 9.12 小结231 习题232 第10章信号233 10.1 引言233 10.2 信号概念233 10.3 signal函数240 10.4 不可靠的信号242 10.5 中断的系统调用244 10.6 可重入函数246 10.7 sigcld语义248 10.8 可靠信号术语和语义250 10.9 kill和raise函数251 10.10 alarm和pause函数252 10.11 信号集256 10.12 sigprocmask函数258 10.13 sigpending函数259 10.14 sigaction函数261 10.15 sigsetjmp和siglongjmp函数266 10.16 sigsuspend函数268 10.17 abort函数274 10.18 system函数276 10.19 sleep函数280 10.20 作业控制信号282 10.21 其他特征284 10.22 小结285 习题285 第11章线程287 11.1 引言287 11.2 线程概念287 11.3 线程标识288 11.4 线程的创建288 11.5 线程终止291 11.6 线程同步297 11.7 小结311 习题311 第12章线程控制313 12.1 引言313 12.2 线程限制313 12.3 线程属性314 12.4 同步属性318 12.5 重入324 12.6 线程私有数据328 12.7 取消选项331 12.8 线程和信号333 12.9 线程和fork 336 12.10 线程和i/o 339 12.11 小结340 习题340 第13章守护进程341 13.1 引言341 13.2 守护进程的特征341 13.3 编程规则342 13.4 出错记录345 13.5 单实例守护进程348 13.6 守护进程的惯例350 13.7 客户进程-服务器进程模型354 13.8 小结354 目录  3 习题354 第14章高级i/o355 14.1 引言355 14.2 非阻塞i/o 355 14.3 记录锁357 14.4 streams 370 14.5 i/o多路转接379 14.5.1 select和pselect函数381 14.5.2 poll函数384 14.6 异步i/o 386 14.6.1 系统v异步i/o 386 14.6.2 bsd异步i/o 387 14.7 readv和writev函数387 14.8 readn和writen函数389 14.9 存储映射i/o 390 14.10 小结395 习题396 第15章进程间通信397 15.1 引言397 15.2 管道398 15.3 popenpclose函数403 15.4 协同进程408 15.5 fifo 412 15.6 xsi ipc 415 15.6.1 标识符和键415 15.6.2 权限结构416 15.6.3 结构限制417 15.6.4 优点和缺点417 15.7 消息队列418 15.8 信号量422 15.9 共享存储427 15.10 客户进程-服务器进程属性432 15.11 小结434 习题434 第16章网络ipc:套接字437 16.1 引言437 16.2 套接字描述符437 16.3 寻址439 16.3.1 字节序440 16.3.2 地址格式441 16.3.3 地址查询442 16.3.4 将套接字与地址绑定449 16.4 建立连接450 16.5 数据传输452 16.6 套接字选项464 16.7 带外数据466 16.8 非阻塞和异步i/o 467 16.9 小结468 习题468 第17章高级进程间通信469 17.1 引言469 17.2 基于streams的管道469 17.2.1 命名的streams管道472 17.2.2 唯一连接473 17.3 unix域套接字476 17.3.1 命名unix域套接字477 17.3.2 唯一连接478 17.4 传送文件描述符482 17.4.1 经由基于streams的管道传送 文件描述符484 17.4.2 经由unix域套接字传送文件 描述符486 17.5 open服务器版本1 493 17.6 open服务器版本2 498 17.7 小结505 习题505 第18章终端i/o507 18.1 引言507 18.2 综述507 18.3 特殊输入字符512 18.4 获得和设置终端属性516 18.5 终端选项标志516 18.6 stty命令522 18.7 波特率函数523 18.8 行控制函数524 18.9 终端标识524 18.10 规范模式529 18.11 非规范模式532 18.12 终端的窗口大小537 18.13 termcap,terminfo和curses 539 4 目录 18.14 小结540 习题540 第19章伪终端541 19.1 引言541 19.2 概述541 19.3 打开伪终端设备544 19.3.1 基于streams的伪终端547 19.3.2 基于bsd的伪终端549 19.3.3 基于linux的伪终端551 19.4 pty_fork函数553 19.5 pty程序555 19.6 使用pty程序559 19.7 高级特性564 19.8 小结565 习题565 第20章数据库函数库567 20.1 引言567 20.2 历史567 20.3 函数库568 20.4 实现概述569 20.5 集中式或非集中式572 20.6 并发574 20.7 构造函数库574 20.8 源代码575 20.9 性能598 20.10 小结600 习题601 第21章与网络打印机通信603 21.1 引言603 21.2 网络打印协议603 21.3 超文本传输协议605 21.4 打印假脱机技术605 21.5 源代码607 21.6 小结644 习题645 附录a 函数原型647 附录b 其他源代码677 附录c 部分习题答案685 参考书目709 索引715
目录 封面 -12 封底 -11 扉页 -10 版权 -9 版权声明 -8 前言 -7 目录 -3 第一部分 简介 1 第1章 简介 2 1.1 概述 2 1.2 进程、线程与信息共享 3 1.3 IPC对象的持续性 4 1.4 名字空间 5 1.5 fork、exec和exit对IPC对象的影响 7 1.6 出错处理:包裹函数 8 1.7 Unix标准 9 1.8 书中IPC例子索引表 11 1.9 小结 13 习题 13 第2章 Posix IPC 14 2.1 概述 14 2.2 IPC名字 14 2.3 创建与打开IPC通道 16 2.4 IPC权限 18 2.5 小结 19 习题 19 第3章 System V IPC 20 3.1 概述 20 3.2 key_t键和ftok函数 20 3.3 ipc_perm结构 22 3.4 创建与打开IPC通道 22 3.5 IPC权限 24 3.6 标识符重用 25 3.7 ipcs和ipcrm程序 27 3.8 内核限制 27 3.9 小结 28 习题 29 第二部分 消息传递 31 第4章 管道和FIFO 32 4.1 概述 32 4.2 一个简单的客户-服务器例子 32 4.3 管道 32 4.4 全双工管道 37 4.5 popenpclose函数 39 4.6 FIFO 40 4.7 管道和FIFO的额外属性 44 4.8 单个服务器,多个客户 46 4.9 对比迭代服务器与并发服务器 50 4.10 字节与消息 51 4.11 管道和FIFO限制 55 4.12 小结 56 习题 57 第5章 Posix消息队列 58 5.1 概述 58 5.2 mq_open、mq_close和mq_unlink函数 59 5.3 mq_getattr和mq_setattr函数 61 5.4 mq_send和mq_receive函数 64 5.5 消息队列限制 67 5.6 mq_notify函数 68 5.7 Posix实时信号 78 5.8 使用内存映射I/O实现Posix消息队列 85 5.9 小结 101 习题 101 第6章 System V消息队列 103 6.1 概述 103 6.2 msgget函数 104 6.3 msgsnd函数 104 6.4 msgrcv函数 105 6.5 msgctl函数 106 6.6 简单的程序 107 6.7 客户-服务器例子 112 6.8 复用消息 113 6.9 消息队列上使用select和poll 121 6.10 消息队列限制 122 6.11 小结 124 习题 124 第三部分 同步 125 第7章 互斥锁和条件变量 126 7.1 概述 126 7.2 互斥锁:上锁与解锁 126 7.3 生产者-消费者问题 127 7.4 对比上锁与等待 131 7.5 条件变量:等待与信号发送 132 7.6 条件变量:定时等待和广播 136 7.7 互斥锁和条件变量的属性 136 7.8 小结 139 习题 139 第8章 读写锁 140 8.1 概述 140 8.2 获取与释放读写锁 140 8.3 读写锁属性 141 8.4 使用互斥锁和条件变量实现读写锁 142 8.5 线程取消 148 8.6 小结 153 习题 153 第9章 记录上锁 154 9.1 概述 154 9.2 对比记录上锁与文件上锁 157 9.3 Posix fcntl记录上锁 158 9.4 劝告性上锁 162 9.5 强制性上锁 164 9.6 读出者和写入者的优先级 166 9.7 启动一个守护进程的唯一副本 170 9.8 文件作锁用 171 9.9 NFS上锁 173 9.10 小结 173 习题 174 第10章 Posix信号量 175 10.1 概述 175 10.2 sem_open、sem_close和sem_unlink函数 179 10.3 sem_wait和sem_trywait函数 180 10.4 sem_post和sem_getvalue函数 180 10.5 简单的程序 181 10.6 生产者-消费者问题 186 10.7 文件上锁 190 10.8 sem_init和sem_destroy函数 191 10

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liranke

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值