UNIX网络编程——客户/服务器程序设计示范(五)
TCP预先派生子进程服务器程序,传递描述符
对预先派生子进程服务器程序的最后一个修改版本是只让父进程调用accept,然后把所接受的已连接套接字“传递”给某个子进程。这么做绕过了为所有子进程的accept调用提供上锁保护的可能需求,不过需要从父进程到子进程的某种形式的描述符传递。这种技术会使代码多少有点复杂,因为父进程必须跟踪子进程的忙闲状态,以便给空闲子进程传递新的套接字。
在以前的预先派生子进程的例子中,父进程无需关心由哪个子进程接收一个客户连接。操作系统处理这个细节,给予某个子进程以首先调用accept的机会,或者给予某个子进程以所需的文件锁或互斥锁。
然而对于当前的预先派生子进程例子,我们必须为每个子进程维护一个信息结构以便管理。如下给出child的结构。
我们在该结构中存放相应子进程的进程ID,父进程中连接到该子进程的字节流管道描述符,子进程状态以及该子进程已处理客户的计数。我们的SIGINT信号处理函数将在终止程序前显示各个子进程的这个计数器值,以便观察全体客户请求在各个子进程之间的发布。
如下给出child_make函数。在调用fork之前先创建一个字节流管道。派生出子进程后,父进程关闭其中一个描述符(sockfd[1]),子进程关闭另一个描述符(sockfd[0])。父进程还把流管道的自身拥有端(sockfd[1])复制到标准错误输出,这样每个子进程就通过读写标准错误输出和父进程通信。父子进程之间的关系如图30-22所示。
#include "unp.h"
#include "child.h"
typedef struct {
pid_t child_pid; /* process ID */
int child_pipefd; /* parent's stream pipe to/from child */
int child_status; /* 0 = ready */
long child_count; /* # connections handled */
} Child; Child *cptr; /* array of Child structures; calloc'ed */ pid_t
child_make(int i, int listenfd, int addrlen)
{
int sockfd[2];
pid_t pid;
void child_main(int, int, int); Socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd); if ( (pid = Fork()) > 0) {
Close(sockfd[1]);
cptr[i].child_pid = pid;
cptr[i].child_pipefd = sockfd[0];
cptr[i].child_status = 0;
return(pid); /* parent */
} Dup2(sockfd[1], STDERR_FILENO); /* child's stream pipe to parent */
Close(sockfd[0]);
Close(sockfd[1]);
Close(listenfd); /* child does not need this open */
child_main(i, listenfd, addrlen); /* never returns */
}
void
child_main(int i, int listenfd, int addrlen)
{
char c;
int connfd;
ssize_t n;
void web_child(int); printf("child %ld starting\n", (long) getpid());
for ( ; ; ) {
if ( (n = Read_fd(STDERR_FILENO, &c, 1, &connfd)) == 0)
err_quit("read_fd returned 0");
if (connfd < 0)
err_quit("no descriptor from read_fd"); web_child(connfd); /* process request */
Close(connfd); Write(STDERR_FILENO, "", 1); /* tell parent we're ready again */
}
}

UNIX网络编程——客户/服务器程序设计示范(五)的更多相关文章
- UNIX网络编程——客户/服务器程序设计示范(总结)
(1)当系统负载较轻是,每来一个客户请求现场派生一个子进程为之服务的传统并发服务器程序模型就足够了.这个模型甚至可以与inetd结合使用,也就是inetd处理每个连接的接收.我们的其他意见是就重负荷运 ...
- UNIX网络编程——客户/服务器程序设计示范(八)
TCP预先创建线程服务器程序,主线程统一accept 最后一个使用线程的服务器程序设计示范是在程序启动阶段创建一个线程池之后只让主线程调用accept并把每个客户连接传递给池中某个可用线程. ...
- UNIX网络编程——客户/服务器程序设计示范(七)
TCP预先创建线程服务器程序,每个线程各自accept 前面讨论过预先派生一个子进程池快于为每个客户线程派生一个子进程.在支持线程的系统上,我们有理由预期在服务器启动阶段预先创建一个线程池以取 ...
- UNIX网络编程——客户/服务器程序设计示范(六)
TCP并发服务器程序,每个客户一个线程 前面讲述了,每个客户一个进程的服务器,或为每个客户现场fork一个子进程,或者预先派生一定数目的子进程.如果服务器主机支持线程,我们就可以改用线程以取代子进程. ...
- UNIX网络编程——客户/服务器程序设计示范(三)
TCP预先派生子进程服务器程序,accept无上锁保护 我们的第一个"增强"型服务器程序使用称为预先派生子进程的技术.使用该技术的服务器不像传统意义的并发服务器那样为每个客户现场派 ...
- UNIX网络编程——客户/服务器程序设计示范(二)
TCP并发服务器程序,每个客户一个子进程 传统上并发服务器调用fork派生一个子进程来处理每个客户.这使得服务器能够同时为多个客户服务,每个进程一个客户.客户数目的唯一限制是操作系统对以其名义 ...
- UNIX网络编程——客户/服务器程序设计示范(一)
下面给出的是客户程序用于测试我们的服务器程序的各个变体. #include "unp.h" #define MAXN 16384 /* max # bytes to request ...
- UNIX网络编程——客户/服务器程序设计示范(四)
TCP预先派生子进程服务器程序,accept使用线程上锁保护 我们使用线程上锁保护accept,因为这种方法不仅适用于同一进程内各线程之间的上锁,而且适用于不同进程之间的上锁. ...
- UNIX网络编程——客户/服务器心搏函数
阅读此博客时,可以参考以前的博客<<UNIX网络编程--socket的keep-alive>>和<<UNIX网络编程--套接字选项(心跳检测.绑定地址复用)> ...
随机推荐
- Python中的文件路径的分隔符
主要是需要考虑分隔符的问题: 在Windows系统下的分隔符是:\ (反斜杠). 在Linux系统下的分隔符是:/(斜杠). 当在字符中出现\时,大家就要考虑到转义字符了. 转义字符的概念,参考维基百 ...
- Mysql优化--Show Profile
Mysql 系列文章主页 =============== 是Mysql提供可以用来分析当前会话中语句执行的资源消耗情况.可以用于Sql的调优的测量.默认情况下处于关闭状态,并保存最近 15 次的运行结 ...
- 【Java关键字-Interface】为什么Interface中的变量只能是 public static final
三个关键字在接口中的存在原因:public:接口可以被其他接口继承,也可以被类实现,类与接口.接口与接口可能会形成多层级关系,采用public可以满足变量的访问范围: static:如果变量不是sta ...
- Spring--AOP 例子
先用代码讲一下什么是传统的AOP(面向切面编程)编程 需求:实现一个简单的计算器,在每一步的运算前添加日志.最传统的方式如下: Calculator.Java package cn.limbo.spr ...
- Logistic Regression 算法向量化实现及心得
Author: 相忠良(Zhong-Liang Xiang) Email: ugoood@163.com Date: Sep. 23st, 2017 根据 Andrew Ng 老师的深度学习课程课后作 ...
- python学习之路网络编程篇(第四篇)
python学习之路网络编程篇(第四篇) 内容待补充
- python笔记九(迭代)
一.迭代 通过for循环来遍历一个列表,我们称这种遍历的方式为迭代.只要是可迭代对象都可以进行迭代操作. 以下代码可以用来判断一个对象是否是可迭代的. 一类是集合数据类型,如list.tuple.di ...
- Radio Station
B. Radio Station time limit per test: 2 seconds memory limit per test: 256 megabytes input: standa ...
- Python3 XML解析
什么是XML? XML 指可扩展标记语言(eXtensible Markup Language),标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言. 你可以通过本站学习XML教程 ...
- [图论]最大流问题(Maximum flow)的定义
首先定义网络(network)N =(V,E), V表示顶点(Vertices)集合, E表示边(Edges)集合. s,t是V中的两个顶点,分别表示网络N中的源点(source)和汇点(sink). ...