I am trying to make an interactive terminal application with a tui in C. I can get blocking keyboard input with getc/read and get resizesignal (SIGWINCH) with waitsig, but then I need to have multiple threads because they are blocking. Or I can check for non blocking keypress and terminal resize in a loop with ioctl, but then either the cpu usage is high or I have to sleep some time (which increases the latency). Is there a better way to do this? Or a function that waits for ANY terminal event, so I only need one extra thread? The main thread is going to be used to draw/update the terminal screen.
I tried to have a mainloop that checks for keypress and terminal resize every time it draws, but this is really inefficient.
Related
I am trying to understand basic signals concepts so I can write a program that handles every possible signal printing its id on the screen.
I don’t know what means every possible signals. I have read that we can get all signals handled by system using kill -l commands so do I understand it properly that I should write a program that handles all those 64 signals? I’ve also read that some signals can be sent to the process by keyboard shortcuts but How many signals are there that are sent in that way - I managed to find only Ctrl-C, Ctrl-Z, Ctrl-. So How to send the rest of the signals to program if there are no shortcuts for the rest of the signals? I can’t get over It for whole day long, asking in forum was my last step I took, Not the first one.
I wrote a CPU intensive program in C to run on Windows. In the main loop I check for a keyboard press to allow you to interrupt execution in order to pause the program. The idea is to release the thread to other processes if the program is slowing down the computer too much. After a keyboard press I wait for more keyboard input using fgets(), which allows you to restart the program later. This does reduce the CPU usage shown in task manager quite well. But I was wondering if there is perhaps a more explicit way to tell the operating system that this process doesn't need any attention for a while in order to reduce the overhead while idle to the absolute minimum.
My understanding is that the operating system periodically lets a process run and then stops running it after a certain amount of time. It then checks the rest of the processes in the same way until it comes back to this one again. If it has enough to do the process will run for the maximum allowed time. Otherwise, it will stop early and return control to the operating system. So a function like fgets must immediately return control if there is no keyboard input, which is why the process runs at near 0% CPU. So I guess another way of asking my question is how do I deliberately return control to the operating system in my own code.
my question is how do I deliberately return control to the operating system in my own code
You can use either Sleep(0) or SwitchToThread(). Both pass control back to the OS and might cause the calling thread to give up the remaining time slice but the devil is in the detail.
Sleep(0)
If no other thread with a matching priority is ready to run, the call returns immediately. Otherwise, the thread gives up its remaining time slice.
You can work around the priority issue by using SwitchToThread or Sleep(1). The disadvantage of the latter is that the thread gives up its time slice unconditionally, whether or not other threads are ready to run.
SwitchToThread()
If no other thread, irrespective if its priority, is ready to run on the thread's current processor, the call returns immediately. Otherwise, the thread gives up its remaining time slice for at most one time slice.
Alternatively, you could change the priority of the process (SetPriorityClass() with PROCESS_MODE_BACKGROUND_BEGIN) or thread (SetThreadPriority() with THREAD_MODE_BACKGROUND_BEGIN) so that the OS can take care of prioritizing more important processes/threads for you. In your scenario, doing so would be a better fit. The scheduler will respond to sudden CPU demand without any additional work on your end.
You can do it in pretty much two ways. Either read the input using a blocking function, like fgets, or read the input using a non-blocking function. In the second situation you would need to incorporate a timeout of some sort. Some functions do this for you, like select. Otherwise you need to regularly sleep your process or thread.
Effectively the system is using interrupts to determine which processes care about a specific event.
My main application is parsing data from an audio device which continously streams data. I want to be able to let the user press any key to stop the process where my application then will stop parsing and save all received data to a file.
The parsing loop look much like this:
while(1)
{
audio_read(buf);
}
So consecutively, I want to listen for a key input to stop this execution. I do not want to poll for key while reading the audio data since this has to operate as fast as possible.
I have tried reading Microsofts documentation but I really don't understand how to easily set up the code for executing functions in different threads.
One thread will wait for the keypress, and set a boolean flag. The thread that is processing audio data needs to periodically check to see if this flag is set.
How would I run a constant process in the background while there is a gtk system tray icon running? Would I just start two threads and launch the process with one and the system tray icon? Or is there a better way? Sorry, but I am somewhat new to gtk.
If I understand it correctly, then you have an application sitting in the system tray and it needs to periodically check for an external condition.
Your GUI thread can't block for a long time or it would become unresponsive.
I can think of three techniques to solve this:
Use a timer to periodically poll from the main (GUI) thread (g_timeout_add() or similar).
Create a separate thread which runs a busy-wait loop (check for the condition; sleep; check; rinse and repeat). Glib has support for thread abstraction which you could use; example GThread usage in Brasero.
Use asyncronous IO to check for the condition. If you are monitoring a file or directory for changes, then you could use GFileMonitor from GIO.
I don't think you need any threads in your example. What do you exactly call a "constant process"?
Either it is:
a blocking processing function you made, an you can do your processing in a callback that will be called when your program is idle, by splitting it in several parts (see g_idle_add and an example of lazy loading)
or it is what is commmonly called a process (with a PID), and as it runs in a completely separate process, you don't need threads either. Read the official documentation to learn how to spawn a process from a GTK application.
Is there a way to create a timer (say, to 10 seconds) on a different thread?
I mean, I know how to use CreateThread() and I know how to create/use timers. The problem I have is that the new thread cannot receive a callback function.
For those that will inevitably ask "why do you want to do this?" the answer is because i have to do it this way. it is part of a bigger program that can't at this specific part of the code use callback functions. that's all.
Is there any way to achieve this?
code is appreciated.
Thanks!
EDIT:
A better explanation of the problem:
My application consist of two separate programs. The main program (visible, interface for the user) and another doing the hard work in the background (sort of like a daemon).
The background process need to finishing writing to the DB and closing a lot of little files before exiting.
The main application send a "we're done" message to that background process. Upon receiving this the background process returns the current status and exists.
Now, I need to add the following: upon receiving the message it returns a status and triggers a timer that will wait X amount of time on another thread, in the meantime the background process closes all the DB connections and files. If the timer reached 0 then and the background process is still alive then it terminates it. If the background process closed all the db and files then the thread (and timer) will die before reaching 0 as the application terminates normally.
Is this better?
So, you need a watchdog inside the DB process (I misread again, didn't I). ThreadProc like this will probably suffice, since all threads terminates when main thread terminates:
DWORD WINAPI TerminateAfter10s(LPVOID param) {
Sleep(10000);
ExitProcess(0);
}
If you use the multimedia timer function timeSetEvent, it can be configured to pulse an event rather than use the normal callback. Does that satisfy the requirement ?
I'm more interested in knowing why you have this requirement to avoid the use of a callback. Callbacks would seem to be entirely appropriate to use in a worker thread.