5

I have a program where I record data through an ADC system from National Instruments (NI).

The device buffers information for some time, and then the program collects the buffer data at some point. If the program collects data larger than the buffer, then the buffer would have to free without my program receiving the data, which will cause the NI library to throw an exception saying that requested data isn't available anymore, since it was lost.

Since my program is a command-prompt program, if the user clicks and holds the scrollbar, the program pauses, which could get this problem to happen.

How can I get over this problem without increasing the buffer size? Can I disable this holding thing in Windows?

Thanks.

The Quantum Physicist
  • 24,987
  • 19
  • 103
  • 189

4 Answers4

4

Only the thread that is attempting to output to the console is blocked. Make this a separate thread, and your problem goes away.

Of course, you'll need to buffer up your output, and do something sensible if the buffer overflows.

For reference, here's the simple code I used to test this, you will note that the counter continues to increase even when the scroll bar is held down:

#include <Windows.h>
#include <stdio.h>

volatile int n = 0;

DWORD WINAPI my_thread(LPVOID parameter)
{
    for (;;)
    {
        n = n + 1;
        Sleep(800);
    }
}

int main(int argc, char ** argv)
{
    if (!CreateThread(NULL, 0, my_thread, NULL, 0, NULL))
    {
        printf("Error %u from CreateThread\n", GetLastError());
        return 0;
    }
    for (;;)
    {
        printf("Hello!  We're at %u\n", n);
        Sleep(1000);
    }
    return 0;
}
Harry Johnston
  • 35,639
  • 6
  • 68
  • 158
  • This method looks great, but I'm pretty worried about communicating data between my sub-thread and main thread. Any ideas about that other than global variables? – The Quantum Physicist Feb 12 '13 at 20:41
  • +1 for example code(I don't have Windows machine readily available - need to get my Widnows VM running, really!). This is the solution I suggested. As to communication, it really depends on what your data looks like and how you want to deal with any problems like "the main thread is WAY behind the collecting data thread. You will (probably) need some sort of synchronization between the collecting data thread and the main thread. There are quite a few solutions, and it's really not easy to say... – Mats Petersson Feb 12 '13 at 23:50
  • The example code provided is, of course, only intended to demonstrate that it really is only the output thread that gets delayed. Production code would need to be made thread-safe. You don't need global variables, you can use the `parameter` variable to pass the address of a structure containing whatever data the thread needs; see the documentation for CreateThread. As for a communication method, perhaps a singly linked list? http://msdn.microsoft.com/en-us/library/windows/desktop/ms686962%28v=vs.85%29.aspx – Harry Johnston Feb 13 '13 at 00:45
  • The timing for the acquisition thread is not a problem, because it's determined by the acquisiton system (just like your sleep function, more or less, but instead I have data collection that makes the program wait), but my problem is the way of sending and receiving data from the thread. In Qt, I know how to do this, where data can be passed as objects continuously by reference. But on Windows threads, I'm not sure. That's why I'm asking for the possibilities. I hope you guys have an answer with a simple example of communicating at least an arraying between the main thread and the sub-thread. – The Quantum Physicist Feb 13 '13 at 08:18
  • Do the output messages have to be displayed in the order they were generated? – Harry Johnston Feb 14 '13 at 02:42
3

Whilst there may be ways to bypass each individual problem you can possibly conceive with the output [including for example running it over a network on a sometimes slow output link, or some such], I think the correct thing to do is to disconnect your output from your collecting of data. It shouldn't be hard to do this by adding a separate thread that collects the data, and having the main thread display to the command prompt window. That way, not matter which variation of "output is blocked" Windows throws at you, it will work - at least until you run out of RAM, but tat that point it's YOUR program's decision to do something [e.g. throw away some data or some such].

This is generally how the problem "I need to collect something, and I also need to allow users to view the data, but I don't want the two to interfere with each other" is solved.

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
2

First use the GetConsoleWindow winapi function and get the HWND of your console. now i suggest two ways to do this,

Method I Subclass the window by creating your own WindowProcedure. (get help from here) Now that you have subclassed it, you can intercept the WM_VSCROLL and WM_HSCROLL messages and do your own remedy to your code.

Method II Change the size of the window using some function like SetWindowPos so that the scroll bars are not needed. or Change the size of the console screen buffer so that the scroll bars are not needed.

Method I has lot of control over the application, but its a little bit complex than the method II which is very simple. If you want to forbid the user from resizing the console window, just remove the WS_THICKFRAME from the WindowStyle of the console window.

Deamonpog
  • 805
  • 1
  • 10
  • 24
0

I was in a similar situation and found that this kind of blocking behaviour could be caused by the quick edit "feature" of the command prompt. This question explains about it and the answer shows how to disable it. Hope that helps, even after some years :)

gustavovelascoh
  • 1,208
  • 1
  • 14
  • 28