我不知道为啥我的 IOCP 的 numberOfConcurrentThreads 参数不起作用

Posted

技术标签:

【中文标题】我不知道为啥我的 IOCP 的 numberOfConcurrentThreads 参数不起作用【英文标题】:I don't know why my IOCP's numberOfConcurrentThreads argument doesn't work我不知道为什么我的 IOCP 的 numberOfConcurrentThreads 参数不起作用 【发布时间】:2021-11-22 13:45:58 【问题描述】:

我已阅读下面的材料并测试了一些代码。 Does IOCP creates its own threads?

我的代码如下:

#include <functional>
#include <stdio.h>
#include <iostream>
#include <crtdbg.h>
#include <conio.h>
#include <array>
#include <unordered_map>
using namespace std;

namespace IOCP_test 
    struct myOverlapped 
        OVERLAPPED overLapped;
        int number;
    ;

    DWORD WINAPI myCallBack(LPVOID completionPort) 
        DWORD NumberOfByteTransfered = 0;
        VOID* CompletionKey = NULL;
        OVERLAPPED* overlappedPointer = NULL;


        while (true) 
            auto success = GetQueuedCompletionStatus(
                (HANDLE)completionPort,
                &NumberOfByteTransfered,
                (LPDWORD)&CompletionKey,
                &overlappedPointer,
                INFINITE);


            if (success) 
                myOverlapped* mO = (myOverlapped*)overlappedPointer;
                while (true) 
                    cout << mO->number << endl;
                
                //Sleep(10);
                //PostQueuedCompletionStatus(completionPort, 0, 0, overlappedPointer);
            
        
    


    void IOCP_test()  
        // TODO: sleep을 안걸었는데.. 왜 5개 스레드가 모두 작동할까?
        int workerThreadCount = 5; 
        HANDLE hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
        vector<HANDLE> workerThreadVector;

        DWORD NumberOfByteTransfered = 0;
        VOID* CompletionKey = NULL;
        OVERLAPPED* overlappedPointer = NULL;

        for (DWORD i = 0; i < workerThreadCount; i++)
        
            HANDLE WorkerThread = CreateThread(NULL, 0, myCallBack, hIOCP, 0, NULL);
            workerThreadVector.push_back(WorkerThread);
        

        myOverlapped a1;
        a1.number = 1;

        myOverlapped a2;
        a2.number = 2;

        myOverlapped a3;
        a3.number = 3;

        myOverlapped a4;
        a4.number = 4;

        myOverlapped a5;
        a5.number = 5;

        if (hIOCP) 
            PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a1);
            PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a2);
            PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a3);
            PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a4);
            PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a5);
        

        char key;
        while (true) 
            key = _getch();

            if (key == 'e') 
                break;
            

            if (key == 'n') 
                cout << endl;
            
        

        for (DWORD i = 0; i < workerThreadVector.size(); i++)
        
            CloseHandle(workerThreadVector[i]);
        

        if (hIOCP) 
            CloseHandle(hIOCP);
        
    
    //IOCP_test::IOCP_test();



int main()

    IOCP_test::IOCP_test();
    _CrtDumpMemoryLeaks();  
    return 0;

我想,如果 numberOfConcurrentThreads 有效,那么应该只运行一个 cout '1' 的线程,而不是所有五个线程。

但是,结果如下。

所有重叠的工作都由工作线程处理..

为什么所有重叠的工作都由 5 个工作线程处理? 我认为应该是 1 个工作线程,因为 numberOfConcurrentThreads 是 1。

我希望您的明智回答。 感谢您的阅读。

【问题讨论】:

和?你的代码什么都没有显示。 你没看到我上面的代码吗? 一些代码,和?它与您关于 numberOfConcurrentThreads 的问题有何关系? 抱歉迟到了。我整天都在工作。你可以在下面的链接上看到“numberOfConcurrentThreads”是什么。 docs.microsoft.com/en-us/windows/win32/api/ioapiset/… 这是函数'CreateIoCompletionPort'的第四个参数,它控制IOCP上正在运行的工作线程的数量。 【参考方案1】:

我想通了。 这是因为我在工作线程的函数中调用了“cout”。 我认为 'cout' 为我的工作线程调用 IO 中断,它使 IOCP 向另一个工作线程发出信号。

我的测试代码如下。 您可以运行此代码,然后按除“e”以外的任何键。(“e”用于退出。) 您可以在 IOCP 中查看哪个工作线程在工作。

#include <functional>
#include <stdio.h>
#include <iostream>
#include <crtdbg.h>
#include <conio.h>
#include <array>
#include <unordered_map>

int iocp_test = -1;


namespace IOCP_test 
    struct myOverlapped 
        OVERLAPPED overLapped;
        int number;
    ;

    DWORD WINAPI myCallBack(LPVOID completionPort) 
        DWORD NumberOfByteTransfered = 0;
        VOID* CompletionKey = NULL;
        OVERLAPPED* overlappedPointer = NULL;


        while (true) 
            auto success = GetQueuedCompletionStatus(
                (HANDLE)completionPort,
                &NumberOfByteTransfered,
                (LPDWORD)&CompletionKey,
                &overlappedPointer,
                INFINITE);


            if (success) 
                myOverlapped* mO = (myOverlapped*)overlappedPointer;
                while (true) 
                    iocp_test = mO->number;
                
                //Sleep(10);
                //PostQueuedCompletionStatus(completionPort, 0, 0, overlappedPointer);
            
        
    


    void IOCP_test()  
        // sleep을 안걸었는데.. 왜 5개 스레드가 모두 작동할까? 
        // cout 같은 IO 인터럽트가 워커 스레드에서 호출되면 IOCP에서 그 스레드는 작업 중이 아닌 스레드로 판단하는 것 같다.
        int workerThreadCount = 5; 
        HANDLE hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 2); 
        vector<HANDLE> workerThreadVector;

        DWORD NumberOfByteTransfered = 0;
        VOID* CompletionKey = NULL;
        OVERLAPPED* overlappedPointer = NULL;

        for (DWORD i = 0; i < workerThreadCount; i++)
        
            HANDLE WorkerThread = CreateThread(NULL, 0, myCallBack, hIOCP, 0, NULL);
            workerThreadVector.push_back(WorkerThread);
        

        myOverlapped a1;
        a1.number = 1;

        myOverlapped a2;
        a2.number = 2;

        myOverlapped a3;
        a3.number = 3;

        myOverlapped a4;
        a4.number = 4;

        myOverlapped a5;
        a5.number = 5;

        if (hIOCP) 
            PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a1);
            PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a2);
            PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a3);
            PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a4);
            PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a5);
        

        char key;
        while (true) 
            key = _getch();
            cout << iocp_test;
            if (key == 'e') 
                break;
            

            if (key == 'n') 
                cout << endl;
            

        

        for (DWORD i = 0; i < workerThreadVector.size(); i++)
        
            CloseHandle(workerThreadVector[i]);
        

        if (hIOCP) 
            CloseHandle(hIOCP);
        
    
    //IOCP_test::IOCP_test();




int main()


    IOCP_test::IOCP_test();

    _CrtDumpMemoryLeaks();  
    return 0;

【讨论】:

以上是关于我不知道为啥我的 IOCP 的 numberOfConcurrentThreads 参数不起作用的主要内容,如果未能解决你的问题,请参考以下文章

IOCP 服务器的非 IOCP 客户端发送/接收错误

我的程序崩溃了,我不知道为啥

WSASocket() 应该与 IOCP 一起使用吗?

我的 Heroku 构建一直失败,我不知道为啥

我的应用程序不断崩溃,但我不知道为啥

PowerShell 正在重新排列我的列,我不知道为啥