1、发送数据指导思想
把要发送的数据放到一个队列中,专门创建一个线程来统一负责发送数据。
程序写法千万条,效率稳定第一条。
2、发送数据代码实战
2.1、信号量
sem_post():能够将指定信号量值加1,即便当前没有其它线程在等待该信号量值。
sem_t
线程之间的同步机制。
互斥量,在一个进程的多个线程之间同步。
信号量可以提供进程之间的同步。也可以提供线程之间的同步。
《Unix网络编程 卷2》有讲述。
用之前调用sem_init初始化一下。
用完后用sem_destroy释放信号量。
sem_wait():用来测试指定信号量的值。如果该值大于0,将该值减1然后立即返回。如果该值等于0,那么该线程将投入睡眠中。一直到该值大于0,循环往复。
2.2、数据发送线程
线程函数使用静态成员函数?
2.3、可写通知到达后数据的继续发送
写处理函数,epoll_wait之后调用。
比较重要的函数,需要吃透。
2.4、发送数据的简单测试
如何把发送缓冲区撑满?
观察现象:一次发送65k的数据。发送到第20次,服务端的发送缓冲区才满。
客户端暂时不收数据。
客户端,一次收65k的数据。收益后后服务段缓冲区腾出一部分空间。把没法送出的数据再次发送,然后客户端又可以发送成功16次才满,为什么呢?再次收包,发现服务端发送缓冲区还是满的,收到16次的时候,服务端的发送缓冲区才再次有空闲。如此就往复了。
结论1:水平触发模式下,发送数据采用的改进方案是有效的。在很大程度上提高了效率。
结论2:原来以为发送缓冲区只有十几k的字节。测试成发送了1M多数据,系统才报告发送缓冲区满。当我们发送端调用send发送数据时,操作系统底层已经把数据发送到该连接的接端的接收缓冲区(几百k)。即便接收端不调用recv接收数据。接收缓冲区也会先填满。所以,发送几十k并不能填满发送缓冲区。
结论3:不管怎么测,只要对方不接收数据,发送方的发送缓冲区总会满。
3、发送数据后续处理代码
如果服务端发送缓冲区满,客户端不接收,然后客户端连接断开了。怎么处理?
epoll_wait后可读事件中处理。
加一个标记,断开信号过来的时候,置0;
网友评论