none
Disassociating write to screen - command prompt from execution flow RRS feed

  • Question

  • Hello,

    I am writing to the screen using wprintf() and wcout() at various points in my app in a big while(). Example:

    while(1) {
    	wprintf(L"Hello\n");
    	wcout << L"Hello again\n";
    	WriteToAfile(L"Abcdefgh\n");
    }

    When this is happening if I click on the screen the display freezes that is fine that is what I want but I want the while loop to continue and the write to happen. One solution is creating a thread but then I might end up with creating millions of threads so that is not a viable solution. So is there a way to Disassociate the write to the screen from program execution? In other words if the user clicks and freezes the screen WriteToAFile() should continue unfazed. If creating a write thread is the only solution is there a easy way to prevent millions of thread being created? I would say detect the mouse click and not create any more threads until user hits an ESC to unclick it. I have enclosed a sample program I wrote to demo it. If you can kindly suggest the way to disassociate that would be really very helpful. 

    #include<Windows.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <cstdlib>
    #include<conio.h >
    #include <string>
    #include <iostream>
    #include <istream>
    #include <sstream>
    #include <fstream>
    
    using namespace std;
    wchar_t GCurrentPath[MAX_PATH];
    wofstream GPerfDataLog;
    bool Handler(int CtrlType);
    
    DWORD WINAPI WritePerfCounter(LPVOID lpParameter)
    {
    	while (1)
    	{
    		wprintf(L"sdlfkjssdlfjslfnsldfknslgfnlsdjslfjsldfjsldfjsldfjsldfjsldfjsdlfjsdlfjs;dfj23048723048972384dlfjsdlfjsdlfjsdfjsdfjslfjg\n");
    		Sleep(1000);
    	}
    }
    
    void main()
    {
    	ZeroMemory(GCurrentPath, sizeof(GCurrentPath));
    	GetCurrentDirectoryW(MAX_PATH, GCurrentPath);
    	SetConsoleCtrlHandler((PHANDLER_ROUTINE)Handler, TRUE);
    	
    	CreateThread(NULL, 0, WritePerfCounter, (void*)NULL, 0, NULL);
    	wstring GPerfDataLogPath(GCurrentPath);
    	GPerfDataLogPath += L"\\GPerfDataLog.log";
    	GPerfDataLog.open(GPerfDataLogPath, std::fstream::out);
        while(1)
        {
    		wprintf(L"Thread createdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n");
    		GPerfDataLog << L"I am live\n";
    		Sleep(1000);
        }
    }
    
    bool
    Handler(int CtrlType) {
    	UNREFERENCED_PARAMETER(CtrlType);
    	GPerfDataLog.close();
    	ExitProcess(1);
    }

    Monday, January 6, 2020 2:34 AM

Answers

  • Maybe replace the first sample loop with this one:

     

       while(1)

       {

          MyPrint( L"Hello");

          MyPrint( L"Hello again";

          WriteToAfile( L"Abcdefgh\n");

       }

     

    where MyPrint appends the messages to a queue (e.g. std::queue or std::concurrent_queue) and returns. You will have one special thread that watches this queue, pops and prints the messages.

    Monday, January 6, 2020 6:44 AM
  • I suggest something similar to what Viorel_ said except I think there is a cleaner way. Do everything in a thread except for the console output write to a queue and in the main thread (maybe a separate thread) read from the queue and write to the console. The working thread would set an event when it is done that the main thread checks. It is unlikely your program will ever need to use the Sleep function.

    There is an even simpler and flexible possibility. Your program can write to both the file and the console without doing anything fancy. If the user wants to monitor the output then the command used to execute the program can redirect standard output to the more command using something as in:

    YourProrgam | More

    Or your program can just write to the file and for the standard output (the console) only write status messages. Then the user can use:

    Type thieroutputfile | More

    to see the output, as in the more documentation.



    Sam Hobbs
    SimpleSamples.Info


    • Edited by Simple Samples Monday, January 6, 2020 8:06 AM hit enter too soon
    • Marked as answer by ananda vardhana Monday, January 6, 2020 4:59 PM
    Monday, January 6, 2020 7:49 AM

All replies

  • Maybe replace the first sample loop with this one:

     

       while(1)

       {

          MyPrint( L"Hello");

          MyPrint( L"Hello again";

          WriteToAfile( L"Abcdefgh\n");

       }

     

    where MyPrint appends the messages to a queue (e.g. std::queue or std::concurrent_queue) and returns. You will have one special thread that watches this queue, pops and prints the messages.

    Monday, January 6, 2020 6:44 AM
  • I suggest something similar to what Viorel_ said except I think there is a cleaner way. Do everything in a thread except for the console output write to a queue and in the main thread (maybe a separate thread) read from the queue and write to the console. The working thread would set an event when it is done that the main thread checks. It is unlikely your program will ever need to use the Sleep function.

    There is an even simpler and flexible possibility. Your program can write to both the file and the console without doing anything fancy. If the user wants to monitor the output then the command used to execute the program can redirect standard output to the more command using something as in:

    YourProrgam | More

    Or your program can just write to the file and for the standard output (the console) only write status messages. Then the user can use:

    Type thieroutputfile | More

    to see the output, as in the more documentation.



    Sam Hobbs
    SimpleSamples.Info


    • Edited by Simple Samples Monday, January 6, 2020 8:06 AM hit enter too soon
    • Marked as answer by ananda vardhana Monday, January 6, 2020 4:59 PM
    Monday, January 6, 2020 7:49 AM
  • Thanks to Viorel and Sam, I think I got the idea and I will do it. I will use Viorel's idea and improve is as Sam tells. The more option I cannot use but the queuing of thread is a solution. Thanks a lot. 
    Monday, January 6, 2020 5:01 PM
  • Finally after much struggle I came up with a ideal solution. This basically disable QuickMode but will sense CTRL-C and puts the Command Prompt back in its original state.  Thanks to all helping me out. 
    #include<Windows.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <cstdlib>
    #include<conio.h >
    #include <string>
    #include <iostream>
    #include <istream>
    #include <sstream>
    #include <fstream>
    
    void
    ExitTool();
    
    using namespace std;
    wchar_t GCurrentPath[MAX_PATH];
    wofstream GPerfDataLog;
    bool Handler(int CtrlType);
    
    HANDLE hInput;
    DWORD prev_mode;
    
    void main()
    {
    	SetConsoleCtrlHandler((PHANDLER_ROUTINE)Handler, TRUE);
    	hInput = GetStdHandle(STD_INPUT_HANDLE);
    	GetConsoleMode(hInput, &prev_mode);
    	SetConsoleMode(hInput, prev_mode & ENABLE_EXTENDED_FLAGS);
    	ZeroMemory(GCurrentPath, sizeof(GCurrentPath));
    	GetCurrentDirectoryW(MAX_PATH, GCurrentPath);
    
    	wstring GPerfDataLogPath(GCurrentPath);
    	GPerfDataLogPath += L"\\GPerfDataLog.log";
    	GPerfDataLog.open(GPerfDataLogPath, std::fstream::out);
    	_wsystem(L"cls");
        
    	while(1)
        {
    		wcout << L"slgjdlgjdflgjdfg\n";
    		GPerfDataLog  <<  L" =  I am alive\n";
    		Sleep(1000);
        }
    }
    
    void
    ExitTool()
    {
    	SetConsoleMode(hInput, prev_mode);
    	wcout << L"Ha caught it: " << L"Reset Console Mode once more\n";
    	GPerfDataLog.close();
    	ExitProcess(1);
    }
    
    bool
    Handler(int CtrlType) {
    	UNREFERENCED_PARAMETER(CtrlType);
    	wcout << L"Ha caught it: " << L"Reset Console Mode aur ek baar\n";
    	ExitTool();
    	return(TRUE);
    }
    
    

    Tuesday, January 7, 2020 4:51 PM