我之前写过TCP/IP编程——多线程+非阻塞的服务实现,这篇文章是实现之前需要掌握的知识。
目录
我们网络编程(1)里介绍了单线程的TCP协议。
但是一般生活中,我们的服务都是多线程,并发的,并且是非阻塞的,有利于效率。
在win32库中提供了创建多线程的函数_beginthread与I/O复用函数(实现非阻塞)select
多线程
1.定义多线程的线程函数void workthread(LPVOID lpParam) 【返回值必须是void,传递参数可以用32bit的输入参数,即LPVPOD,LPVOID是一个没有类型的指针】
2.开启线程HANDLE hThread = (HANDLE) _beginthread(workthread, 0, hIOCP)【如果线程创建成功,函数会返回新线程的句柄】
3._endthread函数可以关闭线程。当线程执行完毕也会自动调 用该函数,该函数将释放线程中的所有资源。
多线程同步:锁
win32应用的事件对象机制可以用来通知等待线程某个条件已经满足。
如WriteThread在写完了缓存区的数据后,调用WSASetEvent(evToRead)便可以通知其他在等待的线程执行
没执行WSASetEvent(evToRead)之前,ReadThread通过WSAWaitForMultipleEvents (*,&evToRead,*,*,*)挂起等待事件对象被通知。
当然这两个函数只是win32提供的基础线程同步,还有DWORD WSAAPI WSAWaitForMultipleEvents等函数
非阻塞
调用select可以实现非阻塞。传统recv调用后会阻塞执行直到有数据可读。而select可以同时判断一个套接口(或者套接口集合,fd_set)的多种I/O状态(read、write、exception异常)。每次select返回都至少有一个套接口满足了I/O要求。
函数定义: int select( int nfds, fd_set FAR *readfds, fd_set FAR *writefds fd_set FAR *exceptfds, const struct timeval FAR *timeout);
参数含义: nfds 【 IN 】 : 同时select的套接口个数,已被忽略。
readfds 、 writefds 、 exceptfds 【 INOUT 】 : 描述字集合fd_set指针。
timeout【IN】:以TIMEVAL的形式告诉select函数需要等待的时间