| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 4805 人关注过本帖
标题:WaitForMultipleObjects和WSAWaitForMultipleEvents能否混用
只看楼主 加入收藏
lyl930130
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:323
专家分:111
注 册:2013-5-13
结帖率:91.43%
收藏
已结贴  问题点数:20 回复次数:4 
WaitForMultipleObjects和WSAWaitForMultipleEvents能否混用
如题,感觉两个函数都是对句柄数组进行检测,只是WSAWaitForMultipleEvents仅针对事件句柄(任然是handle),WaitForMultipleObjects针对的句柄种类多。
如果在句柄类型都为事件句柄的情况下,两个函数能否混用?如果能混用,功能上有什么区别?
2016-05-07 11:17
yangfrancis
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:贵宾
威 望:141
帖 子:1510
专家分:7661
注 册:2014-5-19
收藏
得分:20 
没用过这两个,其实也没听到过。楼主不如先举个例普及一下。
2016-05-07 21:38
lyl930130
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:323
专家分:111
注 册:2013-5-13
收藏
得分:0 
回复 2楼 yangfrancis
我照的例子代码比较长,不过可以只看相关函数部分就可以了
2016-05-08 15:13
lyl930130
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:323
专家分:111
注 册:2013-5-13
收藏
得分:0 
WSAWaitForMultipleEvents的例子
程序代码:
//              简单的WSAEventSelect模型                //
//////////////////////////////////////////////////
// WSAEventSelect文件

#include <stdio.h>
#include <WinSock2.h>
#pragma comment (lib,"WS2_32")

int main()
{

 // 事件句柄和套节字句柄表
    WSAEVENT eventArray[WSA_MAXIMUM_WAIT_EVENTS];//64
    SOCKET  sockArray[WSA_MAXIMUM_WAIT_EVENTS];
    int nEventTotal = 0;

    USHORT nPort = 4567; // 此服务器监听的端口号

    // 创建监听套节字
    SOCKET sListen =socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
    sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(nPort);
    sin.sin_addr.S_un.S_addr = INADDR_ANY;
    if(bind(sListen, (sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR)
    {
        printf(" Failed bind() \n");
        return -1;
    }
    listen(sListen, 5);

    // 创建事件对象,并关联到新的套节字
    WSAEVENT event = WSACreateEvent();
    WSAEventSelect(sListen, event, FD_ACCEPT|FD_CLOSE);
    // 添加到表中
    eventArray[nEventTotal] = event;
    sockArray[nEventTotal] = sListen; 
    nEventTotal++;

    // 处理网络事件
    while(TRUE)
    {
        // 在所有事件对象上等待
        int nIndex = WSAWaitForMultipleEvents(nEventTotal, eventArray, FALSE, WSA_INFINITE, FALSE);
        // 对每个事件调用WSAWaitForMultipleEvents函数,以便确定它的状态
        nIndex = nIndex - WSA_WAIT_EVENT_0;
        for(int i=nIndex; i<nEventTotal; i++)
        {
            nIndex = WSAWaitForMultipleEvents(1, &eventArray[i], TRUE, 1000, FALSE);
            if(nIndex == WSA_WAIT_FAILED || nIndex == WSA_WAIT_TIMEOUT)
            {
                continue;
            }
            else
            {
                // 获取到来的通知消息,WSAEnumNetworkEvents函数会自动重置受信事件
                WSANETWORKEVENTS event;
                WSAEnumNetworkEvents(sockArray[i], eventArray[i], &event);
                if(event.lNetworkEvents & FD_ACCEPT)    // 处理FD_ACCEPT通知消息
                {
                    if(event.iErrorCode[FD_ACCEPT_BIT] == 0)
                    {
                        if(nEventTotal > WSA_MAXIMUM_WAIT_EVENTS)
                        {
                            printf(" Too many connections! \n");
                            continue;
                        }
                        SOCKET sNew = accept(sockArray[i], NULL, NULL);
                        WSAEVENT event = WSACreateEvent();
                        WSAEventSelect(sNew, event, FD_READ|FD_CLOSE|FD_WRITE);
                        // 添加到表中
                        eventArray[nEventTotal] = event;
                        sockArray[nEventTotal] = sNew; 
                        nEventTotal++;
                    }
                }
                else if(event.lNetworkEvents & FD_READ)   // 处理FD_READ通知消息
                {
                    if(event.iErrorCode[FD_READ_BIT] == 0)
                    {
                        char szText[256];
                        int nRecv = recv(sockArray[i], szText, strlen(szText), 0);
                        if(nRecv > 0)    
                        {
                            szText[nRecv] = '\0';
                            printf("接收到数据:%s \n", szText);
                        }
                    }
                }
                else if(event.lNetworkEvents & FD_CLOSE)  // 处理FD_CLOSE通知消息
                {
                    if(event.iErrorCode[FD_CLOSE_BIT] == 0)
                    {
                        closesocket(sockArray[i]);
                        for(int j=i; j<nEventTotal-1; j++)
                        {
                            sockArray[j] = sockArray[j+1];
                            eventArray[j] = eventArray[j+1];
                        }
                        nEventTotal--;
                    }
                }
                else if(event.lNetworkEvents & FD_WRITE)  // 处理FD_WRITE通知消息
                {
                }
            }
        }
    }
    return 0;
}
2016-05-08 15:15
lyl930130
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:323
专家分:111
注 册:2013-5-13
收藏
得分:0 
WaitForMultipleObjects的例子
程序代码:
/* ************************************
*《精通Windows API》 
* 示例代码
* Eventm.c
* 7.2.1  演示使用Event同步线程
**************************************/

/* 头文件 */
#include <windows.h>
#include <stdio.h>
/* 常量定义 */
#define NUMTHREADS    3 
#define BUFFER_SIZE    16
#define FOR_TIMES    5
/* 全局变量 */
HANDLE hWriteEvent[NUMTHREADS];        // 写Event 表示写操作是否完成
HANDLE hReadEvents[NUMTHREADS];    // 读Event 表示读操作是否完成
BYTE lpSharedBuffer[16] = {0};    // 共享内存
/* 函数声明 */
void MultiEvents(void);
VOID WriteToBuffer(VOID);
DWORD WINAPI ThreadFunction(LPVOID lpParam);

/*************************************
* int main(void)
* 功能    演示
*
* 参数    未使用
**************************************/
int main()
{
    MultiEvents();
}

/*************************************
* void UseEvents(void) 
* 功能    演示Event的使用方法
*
* 参数    未使用
**************************************/
void MultiEvents(void) 
{
    HANDLE hThread; 
    DWORD i; 
    // 创建多个线程,读共享内存,主线程写共享内存。
    // 每个线程都有对应的读写同步事件
    for(i = 0; i < NUMTHREADS; i++) 
    {
        // 每个线程都有一个Event表示写入操作完成
        hWriteEvent[i] = CreateEvent( 
            NULL,            // 默认安全属性
            FALSE,            // 自动重置
            FALSE,            // 初始为未置位的
            NULL            // 未命名
            );
        // 判断是否创建成功
        if (hWriteEvent[i] == NULL) 
        { 
            printf("CreateEvent failed (%d)\n", GetLastError());
            return;
        }
        // 每个读线程有一个Event表示读操作已经完成
        hReadEvents[i] = CreateEvent( 
            NULL,     // 默认安全属性
            FALSE,      // 自动重置
            FALSE,    // 初始化为未置位的
            NULL);    // 未命名
        if (hReadEvents[i] == NULL) 
        {
            printf("CreateEvent failed (%d)\n", GetLastError());
            return;
        }
        // 创建线程
        hThread = CreateThread(NULL, 0, 
            ThreadFunction, 
            (LPVOID)i,  // Event对象句柄作为
            0, NULL); 
        if (hThread == NULL) 
        {
            printf("CreateThread failed (%d)\n", GetLastError());
            return;
        }
    }
    WriteToBuffer();
}

/*************************************
* VOID WriteToBuffer(INT iContent) 
* 功能    由主线程调用,向共享内存中写入数据
*        等待所有读线程读完后函数返回
*
* 参数    未使用
**************************************/
VOID WriteToBuffer(VOID) 
{
    DWORD dwWaitResult, j,i;
    // 完成 FOR_TIMES 次读写
    for (j = 0; j < FOR_TIMES; j++)
    {        
        Sleep(rand()%100);    // 写入需要的时间随机
        // 写入共享内存
        wsprintf(lpSharedBuffer,"shared %d",j);
        // 将线程对应的写Event置为“标志的”,表示写操作完成,
        // 其他线程可以开始读
        for(i=0; i<NUMTHREADS; i++)
        {
            if (! SetEvent(hWriteEvent[i]) ) 
            { 
                printf("SetEvent failed (%d)\n", GetLastError());
                return;
            }
        }
        // 等待所有的线程读完,开始下次写入
        dwWaitResult = WaitForMultipleObjects( 
            NUMTHREADS,   // Event句柄的个数
            hReadEvents,  // Event句柄数组
            TRUE,         // 等到所有的Event都被标志
            INFINITE);    // 无限等待
        // 判断等待结果
        if (dwWaitResult != WAIT_OBJECT_0) 
        {
            printf("Wait error: %d\n", GetLastError()); 
            ExitProcess(0); 
        }
    }
}

/*************************************
* DWORD WINAPI ThreadFunction(LPVOID lpParam)
* 功能    线程函数,读共享内存
*
* 参数    LPVOID lpParamt 实际为指向Event句柄的指针
**************************************/
DWORD WINAPI ThreadFunction(LPVOID lpParam) 
{
    DWORD dwWaitResult;
    BYTE lpRead[16];
    DWORD j = 0;
    DWORD dwThreadIndex  = (DWORD)lpParam;
    // 完成 FOR_TIMES 次读写
    for(; j<FOR_TIMES; j++)
    {
        // 等待写事件置位,表示数据已经写入
        dwWaitResult = WaitForSingleObject( 
            hWriteEvent[dwThreadIndex], // Event 句柄
            INFINITE);                    // 无限等待
        switch (dwWaitResult) 
        {
        case WAIT_OBJECT_0:
            Sleep(rand()%10);            // 模拟数据处理所需的时间随机
            CopyMemory(lpRead,lpSharedBuffer,16);
            break; 
            // 发生错误
        default: 
            printf("Wait error: %d\n", GetLastError()); 
            ExitThread(0); 
        }
        // 将读Event置位,表示读操作完成
        if (! SetEvent(hReadEvents[dwThreadIndex]) ) 
        { 
            printf("SetEvent failed (%d)\n", GetLastError());
            return 0;
        }
        //打印读到的内容
        printf("线程 %u\t第 %d 次读,内容:%s\n",
            dwThreadIndex,j,(LPSTR)lpRead);
    }
    return 1;
}
2016-05-08 15:20
快速回复:WaitForMultipleObjects和WSAWaitForMultipleEvents能否混用
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.028675 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved