线程同步与异步套接 字编程 主讲人:孙鑫 http://www.sunxin.org
线程同步与异步套接 字编程 主讲人:孙鑫 http://www.sunxin.org
事件对象 事件对象也属于内核对象,包含一个使用计数, 个用于指明该事件是一个自动重置的事件还是 个人工重置的事件的布尔值,另一个用于指明 该事件处于已通知状态还是未通知状态的布尔值 ■有两种不同类型的事件对象。一种是人工重置的 事件,另一种是自动重置的事件。当人工重置的 事件得到通知时,等待该事件的所有线程均变为 可调度线程 个自动重置的事件得到通知时 等待该事件的线程中只有一个线程变为可调度线 程 http://www.sunxin.org
事件对象 ◼ 事件对象也属于内核对象,包含一个使用计数, 一个用于指明该事件是一个自动重置的事件还是 一个人工重置的事件的布尔值,另一个用于指明 该事件处于已通知状态还是未通知状态的布尔值。 ◼ 有两种不同类型的事件对象。一种是人工重置的 事件,另一种是自动重置的事件。当人工重置的 事件得到通知时,等待该事件的所有线程均变为 可调度线程。当一个自动重置的事件得到通知时, 等待该事件的线程中只有一个线程变为可调度线 程。 http://www.sunxin.org
关键代码段 ■关键代码段临界区)工作在用户方式下 关键代码段(临界区)是指一个小代码段,在 代码能够执行前,它必须独占对某些资源 的访问权。 http://www.sunxin.org
关键代码段 ◼ 关键代码段(临界区)工作在用户方式下。 ◼ 关键代码段(临界区)是指一个小代码段,在 代码能够执行前,它必须独占对某些资源 的访问权。 http://www.sunxin.org
线程死锁 ■哲学家进餐的问题 ■线程1拥有了临界区对象A,等待临界区对 象B的拥有权,线程2拥有了临界区对象B 等待临界区对象A的拥有权,就造成了死锁。 http://www.sunxin.org
线程死锁 ◼ 哲学家进餐的问题 ◼ 线程1拥有了临界区对象A,等待临界区对 象B的拥有权,线程2拥有了临界区对象B, 等待临界区对象A的拥有权,就造成了死锁。 http://www.sunxin.org
互斥对象、事件对象与关键代码段 的比较 ■互斥对象和事件对象属于内核对象,利用 内核对象进行线程同步,速度较慢,但利 用互斥对象和事件对象这样的内核对象, 可以在多个进程中的各个线程间进行同步 ■关键代码段是工作在用户方式下,同步速 度较快,但在使用关键代码段时,很容易 进入死锁状态,因为在等待进入关键代码 段时无法设定超时值 http://www.sunxin.org
互斥对象、事件对象与关键代码段 的比较 ◼ 互斥对象和事件对象属于内核对象,利用 内核对象进行线程同步,速度较慢,但利 用互斥对象和事件对象这样的内核对象, 可以在多个进程中的各个线程间进行同步。 ◼ 关键代码段是工作在用户方式下,同步速 度较快,但在使用关键代码段时,很容易 进入死锁状态,因为在等待进入关键代码 段时无法设定超时值。 http://www.sunxin.org
推荐书目 《 Windows核心编程》 机械工业出版社 http://www.sunxin.org
推荐书目 《 Windows核心编程》 机械工业出版社 http://www.sunxin.org
基于消息的异步套接字 ■ Windows套接字在两种模式下执行I/O操作,阻塞和非阻 塞。在阻塞模式下,在I/○操作完成前,执行操作的 Winsock函数会一直等待下去,不会立即返回程序将控制 权交还给程序)。而在非阻塞模式下, Winsock函数无论如 何都会立即返回 ■ Windows sockets为了支持 Windows消息驱动机制,使应用 程序开发者能够方便地处理网络通信,它对网络事件采用 了基于消息的异步存取策略 Windows Sockets的异步选择函数 WSAAsyncSelect提供了消 息机制的网络事件选择,当使用它登记的网络事件发生时 Windows应用程序相应的窗口函数将收到一个消息,消息 中指示了发生的网络事件,以及与事件相关的一些信息
基于消息的异步套接字 ◼ Windows套接字在两种模式下执行I/O操作,阻塞和非阻 塞。在阻塞模式下,在I/O操作完成前,执行操作的 Winsock函数会一直等待下去,不会立即返回程序(将控制 权交还给程序)。而在非阻塞模式下,Winsock函数无论如 何都会立即返回。 ◼ Windows Sockets为了支持Windows消息驱动机制,使应用 程序开发者能够方便地处理网络通信,它对网络事件采用 了基于消息的异步存取策略。 ◼ Windows Sockets的异步选择函数WSAAsyncSelect()提供了消 息机制的网络事件选择,当使用它登记的网络事件发生时, Windows应用程序相应的窗口函数将收到一个消息,消息 中指示了发生的网络事件,以及与事件相关的一些信息
相关函数说明 int WSAEnum Protocols (LPINT piProtocols, LPWSAPROTOCOL_INFO prOtoco Buffer, ILPDWORD /pdw Bufferlength); Win32平台支持多种不同的网络协议,采用 Winsock2,就可以编写可 直接使用任何一种协议的网络应用程序了。通过 WSAEnumProtocols函 数可以获得系统中安装的网络协议的相关信息。 Pm0mb,一个以NU结尾的协议标识号数组。这个参数是可选的, 如果Prm1nk为 则返回所有可用协议的信息,否则,只返回 数组中列出的协议信息。 ■Pm00 colBuffer,om 个用 WSAPROTOCOL INFO结构体填充的缓 冲区。 WSAPROTOCOL INFO结构体用来存放或得到一个指定协议 的完整信息 dn Buffer ength,i,w:在输入时,指定传递给 WSAEnumProtocol 函数的hPmB/缓冲区的长度:在输出时, 获取所有请求 息需传递给 WSAEnumProtocols0函数的最小缓冲区长度。这个函数不 规定 金的答冲必大以便熊征 上装载的协议数目往 往是很少的,所以并不会产生问题
相关函数说明 int WSAEnumProtocols( LPINT lpiProtocols, LPWSAPROTOCOL_INFO lpProtocolBuffer,ILPDWORD lpdwBufferLength ); ◼ Win32平台支持多种不同的网络协议,采用Winsock2,就可以编写可 直接使用任何一种协议的网络应用程序了。通过WSAEnumProtocols函 数可以获得系统中安装的网络协议的相关信息。 ◼ lpiProtocols,一个以NULL结尾的协议标识号数组。这个参数是可选的, 如果lpiProtocols为NULL,则返回所有可用协议的信息,否则,只返回 数组中列出的协议信息。 ◼ lpProtocolBuffer,[out],一个用WSAPROTOCOL_INFO结构体填充的缓 冲区。 WSAPROTOCOL_INFO结构体用来存放或得到一个指定协议 的完整信息。 ◼ lpdwBufferLength,[in, out],在输入时,指定传递给WSAEnumProtocols() 函数的lpProtocolBuffer缓冲区的长度;在输出时,存有获取所有请求信 息需传递给WSAEnumProtocols ()函数的最小缓冲区长度。这个函数不 能重复调用,传入的缓冲区必须足够大以便能存放所有的元素。这个 规定降低了该函数的复杂度,并且由于一个机器上装载的协议数目往 往是很少的,所以并不会产生问题
相关函数说明 SOCKET WSASocket( int af, int type, int protocol, LPWSAPROTOCOL_ INFO ProtocolInfo, GroUP&, DWORD flAgs )i 前三个参数和 socket0函数的前三个参数含义一样 P0mm,一个指向 WSAPROTOCOL INFO结构体的指 针,该结构定义了所创建的套接字的特性。如果 P0mlm为NUL,则 Win Sock2D使用前三个参数来 决定使用哪一个服务提供者,它选择能够支持规定的地址 族、套接字类型和协议值的第一个 j提供 力Pmmm不为NUIL,则套接字绑定到与指定的结 SAPROTOCOL INFO相关的提供者 保留的。 hng,套接字属性的描述
相关函数说明 SOCKET WSASocket( int af, int type, int protocol, LPWSAPROTOCOL_INFO lpProtocolInfo, GROUP g, DWORD dwFlags ); ◼ 前三个参数和socket()函数的前三个参数含义一样。 ◼ lpProtocolInfo,一个指向WSAPROTOCOL_INFO结构体的指 针,该结构定义了所创建的套接字的特性。如果 lpProtocolInfo为NULL,则WinSock2 DLL使用前三个参数来 决定使用哪一个服务提供者,它选择能够支持规定的地址 族、套接字类型和协议值的第一个传输提供者。如果 lpProtocolInfo不为NULL,则套接字绑定到与指定的结构 WSAPROTOCOL_INFO相关的提供者。 ◼ g,保留的。 ◼ dwFlags,套接字属性的描述
相关函数说明 int WSARecvFrom( SOCKET S, LPWSABUF Buffers, dWoRd dw Buffer count LPDWORD Number BytesRecvd, LPDWORD p Flags, struct sockaddr FAR */p From, LPINT p Fromlen, LPWSAOVERLAPPED Overlapped LPWSAOVERLAPPED_COMPLETION_ ROUTINE PComp Routine) ,标识套接字的描述符。 B,,mDm个指向 WSABUF结构体的指针。每一个 WSABUF结构体包 含一个缓冲区的指针和缓冲区的长度 dhB/eCom,B/r数组中 WSABUF结构体的数目 Number Bytesrecydi lout,如果接收操作立即完成,则为一个指向本次调用 所接收的字节数的指针 Fg,Bn,m,一个指向标志位的指针 mm,om,可选指针,指向重叠操作完成后存放源地址的缓冲区 mmbn,in,om,指向from缓冲区大小的指针,仅当指定了mm才需要。 Overlapped,一个指向 WSAOVERLAPPED结构体的指针(对于非重叠套接字则 ( mpletionroutine,一个指向接收操作完成时调用的完成例程的指针(对于非重 叠套接字则忽略
相关函数说明 int WSARecvFrom( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, struct sockaddr FAR *lpFrom, LPINT lpFromlen, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine ); ◼ s,标识套接字的描述符。 ◼ lpBuffers,[in, out],一个指向WSABUF结构体的指针。每一个WSABUF结构体包 含一个缓冲区的指针和缓冲区的长度。 ◼ dwBufferCount, lpBuffers数组中WSABUF结构体的数目。 ◼ lpNumberOfBytesRecvd,[out],如果接收操作立即完成,则为一个指向本次调用 所接收的字节数的指针。 ◼ lpFlags,[in, out],一个指向标志位的指针。 ◼ lpFrom,[out],可选指针,指向重叠操作完成后存放源地址的缓冲区。 ◼ lpFromlen,[in, out],指向from缓冲区大小的指针,仅当指定了lpFrom才需要。 ◼ lpOverlapped,一个指向WSAOVERLAPPED结构体的指针(对于非重叠套接字则 忽略)。 ◼ lpCompletionRoutine,一个指向接收操作完成时调用的完成例程的指针(对于非重 叠套接字则忽略)