UnixSocketV1Chap27ServerClientProgrammDesign

27章 服务器和客户端程序设计方式

一、并发服务器程序,每个客户请求一个进程

定义:调用fork为每个客户端产生一个子进程来处理客户的请求。缺陷是进程的子进程数的限制以及fork消耗的资源。

伪代码流程:

While(1)

{

Fd = Accept

If( 0 ==(pid= fork) )

{

Read

Write

Exit(0)

}

Close(fd)

}

特点:

1.类似HTTP请求,一个请求对应着一个socket以及一个子进程

2.close(fd)也可以不执行,保持连接,下次再有数据过来,则又fork个子进程来进行处理

二、TCP预先派生子进程,accept无上锁保护

定义:在服务器程序启动时,预先生成多个子进程,当一个客户请求达到时,为其分配一个子进程来进行处理。

伪代码流程:

For(nchildNum)

{

If(0 ==(pid=fork) )

{

While(1)

{

Fd = Accept

Read

Write

Close(fd)

}

}

Return pid;

}

特点:

1、每个子进程都具备accept、read、write的操作,不存在服务器程序为每个客户请求分配子进程的操作

2、需要预估客户的总请求数,也就是子进程的数量

3、管理子进程的运行情况,当空闲子进程数量小于一个阈值时,可以继续fork; 当空闲子进程数量大于一个阈值时,可以close。

4、如果再accept之前通过select来监听,则会出现select冲突,当有新连接过来时,内核会通知所有监听此socket的线程,导致select冲突。

三、TCP预先派生子进程,accept有上锁保护

基本流程与二相同,使用MUTEX来保护accept操作,注意与多线程中MUTEX的使用有差异:

1、MUTEX变量必须attach到共享内存中,供多进程使用

2、必须通知线程库,MUTEX变量是在进程间使用的(PTHREAD_PROCESS_SHARED)

四、TCP预先派生子进程,传递描述字

定义:在父进程中accept,然后通过管道将socket描述字传递给子进程,取一个空闲子进程,处理客户请求

伪代码流程:

略(复杂)

特点:

1、需要维护一个结构体数组来保存所有子进程的状态,包括空闲状态、传递的套接字信息等

2、父进程和子进程之间通过管道来传递在父进程accept生成的套接字描述字

3、由于在取空闲子进程时,始终是从子进程数组的第一个元素开始遍历,因此,各个子进程被调用的概率不一样,前面的比后面的概率高很多

五、并发服务器,每个客户请求一个线程

六、预先派生子线程,各个子线程分别accept

七、预先派生子线程,主线程统一accept(无需管道)

八、服务器程序设计小结

1、负载较轻时,并发服务器就够了

2、预先分配子进程(线程),可以减少进程控制CPU时间,大约减少10倍以上。并且编码也不复杂,不过对于实时系统而言,还必须监视空闲子进程数量,并随所服务客户数的动态变化而增加或减少这个数目

3、某些实现允许多个进程或线程阻塞在accept调用上,而另外一些实现,必须使用同步锁来保护accept

4、由于select冲突的存在,让所有子进程或线程阻塞在同一监听套接口的accept调用上要比让他们阻塞在select调用上更为可取。

九、停等方式

定义:简单的循环读写

伪代码流程:

While(get)

{

Write

Read

Put

}

特点:

1、当等待用户输入时,无法监控网络事件

2、停等模式,批处理效率极低

十、Select+阻塞IO

定义:通过select来同时监视用户输入和网路事件

伪代码流程:

While(1)

{

Select(stdin, fd)

If(fd)

Read

If(stdin)

Fgets

write

}

十一、select+非阻塞IO

同十,只需判断返回值

十二、fork版本

伪代码流程:

If( 0 == fork )

{

Whiel(Read)

Fputs(stdout)

}

while( fgets)

write

十三、线程版本

同fork版本

十四、客户端程序设计总结

1、停等模式效率低,通过select同时监控用户输入和网络事件得到改进,使用shutdown来关闭客户到服务器的写socket,来实现批输入操作。

2、双进程和双线程版本中,一个处理从服务器到客户的数据,一个处理从客户到服务器的数据

3、消耗时间,测试从客户到服务拷贝2000行

(1)停等方式,345.0秒

(2)Select+阻塞,12.3秒

(3)Select+非阻塞,6.9秒

(4)Fork双进程,8.7秒

(5)双线程,8.5秒

4、select+非阻塞是最快的,几乎是select+阻塞的两倍。虽然fork双进程比select+非阻塞要慢,但代码简单得多,因此推荐fork版本或者双线程版本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值