0

I have a Windows app that simply runs in the background and watches constantly for data appearing on stdin by means of a separate thread. It does this because it is a Chrome native messaging host and that's how it is expected to communicate with the browser extension (as is clarified in this SO question by RobW). It seems to run fine although imo it uses too much of the cpu when there is no activity. When the browser extension sends bytes on stdin to my app it has to be discovered and processed immediately, and because the processing is intensive an increased demand for cpu usage is understandable, but seems it should not use much when there is no activity.

Disclaimer: I would not call myself an experienced Windows developer.

I am using _beginThreadEx() to launch the function that reads constantly from stdin. The thread is created in InitInstance() like so:

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;

   int nStdInDescriptor = _fileno(stdin);
   hStdIn = (HANDLE) _get_osfhandle(nStdInDescriptor);

   OutputDebugStringA("starting message processing thread function");
   hReadInputThread = (HANDLE)_beginthreadex(0, 0, &threadfunc_processMessages, &i, 0, 0);

   hWnd = CreateWindowEx(WS_EX_TOOLWINDOW, szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!hWnd && !hReadInputThread)
   {
      return FALSE;
   }

   hMainWnd = hWnd;

   return TRUE;
}

and

unsigned int __stdcall threadfunc_processMessages(void* data)
{
    char buffer_temp[STDIN_BUF_SIZE];
    buffer_main = NULL;

    DWORD dwNumBytesRead;
    DWORD dwNumBytesToRead = STDIN_BUF_SIZE;

    while (1) {

        if (ReadFile(hStdIn, buffer_temp, dwNumBytesToRead, &dwNumBytesRead, NULL)) {
            OutputDebugStringA( "Found some bytes on stdin" );

            // byte processing code here. it always processes normally
        }
    }

    return 0;
}

Task Manager shows cpu usage around 49%. I assumed _beginThreadEx() would run in the background, yet still be responsive since it needs to pounce on any data that shows up on stdin. Any help is appreciated.

Alyoshak
  • 2,696
  • 10
  • 43
  • 70
  • how you create thread not play role. play role what thread doing. *I assumed _beginThreadEx() would run in the background* - of course no. – RbMm Jan 29 '20 at 21:57
  • Thank you. I have now found the SetThreadPriority and SetPriorityClass methods. MS docs on _beginthreadex do not even mention priority. If you will compose your comment as an answer to my question I will mark it correct so that others in the community may possibly benefit. – Alyoshak Jan 29 '20 at 22:38
  • no, you are on wrong way. you not need use `SetThreadPriority` and `SetPriorityClass`. you need fix error in your thread code – RbMm Jan 29 '20 at 22:40
  • @RbMm, thank you, please be more specific about the error in my thread code. – Alyoshak Jan 29 '20 at 23:07
  • but you not show your thread code. because this i only can say on 100% that you have error in thread code. you need instead show how you create thread, show what thread doing – RbMm Jan 29 '20 at 23:09
  • I added my thread function. If you read the answer by RobW that I provided you will see my while loop is doing precisely what he says it should do. – Alyoshak Jan 29 '20 at 23:30
  • Imagine what happens when *bVal* is false. It doesn't take that long for the OS to figure out you're doing it wrong, it can do so many, many millions of times per second in a while(1) loop. But that still requires executing code, so you can see that. – Hans Passant Jan 29 '20 at 23:35
  • @Hans, so what should my code do when ReadFile returns false? I do not want to exit the loop, but need to the loop to keep watching for bytes. When ReadFile succeeds everything processes fine (there's a ton of code normally there, that I removed for brevity's sake). – Alyoshak Jan 29 '20 at 23:39
  • 1
    When it returns false then Something Really Bad happened. Like not having a console window you can read from, the normal case in a program that also calls CreateWindowEx(). Trying it over and over again makes no sense, you'll have to re-think it. – Hans Passant Jan 29 '20 at 23:43
  • @Hans, ok so I will definitely handle what happens in case ReadFile returns false. As things are it returns true a lot because the data arrives as expected and processes. So are you saying that my handling a failure will stop it pegging the cpu, or is it there anything wrong with my basic structure of calling ReadFile() in an infinite while loop? – Alyoshak Jan 29 '20 at 23:52
  • `hStdIn` - how opened ? this is synchronous handle ? if yes - need exit from loop after first fail. if not synchronous - loop and separate thread at all wrong. which error return `ReadFile` if it fail ? and at all look at debugger where you spin all time (by set bp) – RbMm Jan 30 '20 at 10:06
  • @RbMm - hStdIn is opened using _get_osfhandle, using the stdin descriptor. This is shown in the code in my question. It is a synchronous handle. I will look at debugger to see whether ReadFile is constantly failing or if it is succeeding but simply returning because no bytes are available for reading. – Alyoshak Jan 30 '20 at 18:37
  • *it is succeeding but simply returning because no bytes are available for reading.* no, this will not be. first what you need do after fail `ReadFile` - call `GetLastError()` and exit from loop. also for get `hStdIn` use `GetStdHandle(STD_INPUT_HANDLE)` and not use global vars – RbMm Jan 30 '20 at 19:00

0 Answers0