Get User Input without Blocking Endless loop - c

I have written a simple C program that basically consists of an endless loop that counts upwards. During the loop, the user is asked for input- and here comes the tricky part: the loop should NOT be blocked while waiting on the user, but display his input as soon as he entered it:
int main(void){
int i;
char dec;
for(;;i++){
printf("%d\n", i);
sleep(5);
if(i==4 || i==8){
printf("Please enter Y or N\n");
dec = fgetc(stdin);
printf("%c\n", dec);
}
}
return 0;
}
I found a similiar question for Python here Python. So do I need to push the user interaction into a new thread with pthread or is there an easier option?
Thanks!
EDIT
int main(void){
int i=0;
char dec;
fd_set input_set;
for(;;i++){
printf("%d\n", i);
sleep(2);
if(i==4 || i==8){
FD_ZERO(&input_set ); /* Empty the FD Set */
FD_SET(0, &input_set); /* Listen to the input descriptor */
dec = select(1, &input_set, NULL, NULL, 0);
}
}
return 0;
}

What you want to do is only possible with system dependent libraries. For instance on Unix you would typically use ncurses to get from the user if they have pressed a button.
The reason it is system dependent is that asynchronous IO is not available for all file system streams. In particular User I/O blocks and that block is unavoidable.
If you are committed to having a multi-threaded program that still uses read/write system calls you would need to have two threads, one for I/O and one for everything else. On the everything else thread you could query some shared memory area and see if the I/O thread has written the correct type of data to this shared memory area.

If you are on linux only, check out this SO post : What are the differences between poll and select?
If you are on both and/or you already have pthreads, then use a separate thread.

If you are using Windows, maybe you can try to use keyboard hooks. See SetWindowsHookEx.
It will capture all the keyboard clicks with callback.
If you are usingLinux, maybe you can use this: Non-blocking keyboard read - C/C++

Related

Complex keyboard input to child process in C, Linux

Ive been trying to solve this one for some time but im unable to come up with a solution. I need a child process to understand complex WASD keyboard input (with complex I mean detect that both W and A or many other keys are being pressed at the same time) but I think that this is impossible in C due to the way characters are read from the terminal. My parent process only best result (taken from another post) is the following:
int kbhit(){
struct timeval tv;
fd_set fds;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds);
select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
return FD_ISSET(STDIN_FILENO, &fds);
}
int main(){
system("stty raw -echo"); //No need to newline to read key and disables showing pressed key
char command;
unsigned short count = 0;
while(1){
while(1){
if(kbhit()){count = 0; command = getchar(); break;}
if(count > 5) {count = 0; command = 'f'; break;}
count++;
//Add code to somehow wait a few milliseconds
}
//Use read key/command...
//If a certain key is read break out of loop
}
system("stty sane echo"); //Return terminal to normal state
return EXIT_SUCCESS;
}
This is way too "hacky" and it does not detect multiple simultaneous key presses and I need a child process to read these keys, this code does not work under a fork since the keyboard is being sent to the parent, the child has no new STDIN (I think). I cant rewrite my entire program in another language due to many low level things im doing elsewhere. Ive thought of the following solutions but im unsure of which one to go for:
Have the child process use system("xterm") to open a new terminal and send keys over this one, this does not solve the multiple keys same time problem and from my first tests im unable to link this new terminal to the running process as this terminal just runs a fresh bash session. Code blocks until this terminal is closed.
Use another language like c++ or java that does support easily reading simultaneous key presses and somehow "pipe" this to the child process. I guess the child would fork and have the other process run this new code with a system call. Im unsure of how to send this to the other process (sockets maybe?).
Are there other better ways of doing this? Would option 2 work? Im lost and stuck, any help is welcome!
The simplest way to do it will be by creating events.
for example
struct SKeyEvent
{
char key;
uint8_t pressed;
};
so when a key is pressed you can use a callback function to update the structure with the key and 0, 1, 2
1 and 2. 1 = pressed, 2=released and followed right away by 0 = idle.
so when I pressed A the function callback will be called with {key:'A', 1}
if you press W same {'W', 1} so you know that A and W are pressed simultaneously.
when a touch is released you will receive 2 calls for example {'A' : 2}, {'A' :0}
I solved this instead of reading characters from the terminal (does not work since you can only input one char a time...) by reading the actual keyboard device (/dev/...). There are some examples of this around.
The downside is that it captures all keyboard input and you now need to run the program as superuser but it works...

C - SIGALRM blocks getchar()

I'm working on a C terminal multiprocess application. The application is menu based, so the user have to choose from the possibilities to do the action. The menu is blocked with a getchar(). Let me show the codepart:
do
{
do
{
printf("\n\n---------------\nMenu\n\n");
printf("1. Option 1\n");
printf("2. Option 2\n");
printf("3. Option 3\n");
printf("4. Exit");
printf("\n\n---------------\n");
scanf("%d", &end);
int c = getchar();
if(end < 1 || end > 4)
{
printf("Try it again!!!\n\n");
}
}
while(end < 1 || end > 4);
}
while(end != 4);
So the user need to choose one of the options. But the problem is that the 2nd option needs to kick off a function in every 5 seconds in the background. One of the children will be handled by the function. So I've created an alarm() handler firstly with the simple signal() method. After that I'm realized that the getchar() I/O process is blocked by received signals. I've tried to create a new child which should handle the stdin processes, and send back the result in a pipe for the parent, but this was not worked too.
Let me share the current signal handling part for better understanding:
// Alarm handling
void CatchAlarm(int sig)
{
if(someCounts > 0)
{
DoSomething();
alarm(5);
}
}
Also the alarm binding:
struct sigaction alarmAction;
alarmAction.sa_handler = CatchAlarm;
sigemptyset(&alarmAction.sa_mask);
alarmAction.sa_flags = SA_RESTART;
sigaction(SIGALRM, &alarmAction, NULL);
My problem is that, I can't send the parent process to sleep, because the user have to be able to do other activities during the alarm is pending. When I get the SIGALRM, the full stdin reading process is going to crazy. Please help me what can I use to block the reading and waiting for user interaction instead of the getchar(), because I've already tried everything. Or if someone can help me how can I solve the issue I can appreciate that.
Of course, if you have further questions or concerns please let me know, and I'm going to update my question as soon as possible.
Thanks in advance
Just put an alarm(5); call before the getchar(); so the kernel is advised to send a SIGALRM signal to interrupt getchar(3). Then, you don't have to put any code inside the signal handler (but you do need the signal handler or the program will be killed, see alarm(2) and kill(2) for an explanation) You'll have to uninstall it after the getchar call either case or the signal handler will be called anyway after 5 seconds, but that's left as an exercise for the reader.
Note on notation
As standard in unix for a long time a reference like getchar(3) means the man page for getchar routine that is located in section 3 of the online unix reference manual. Section 2 is dedicated to system calls and section 3 to library calls historically.

Making this simple code threadsafe

I have just had a really good use for multithreading. As such.... I have to learn multithreading. I have a very simple program:
void *listenloop(void *arg){
while (1){
Sleep(2000);
puts("testing 123\n");
}
return NULL;
}
int main(){
pthread_t listener;
pthread_create(&listener,NULL,listenloop,"foo");
char testinput[200];
while(1){
puts("Scanning: ");
scanf("%s",testinput);
puts("\n\n");
printf("You typed: %s: ",testinput);
}
}
The theory is that it waits for user input, echos it, all while periodically printing.
None to my surprise, actually (and presumably obviously to my betters in the matter) the output is "messed up."
Now I can think of several ways around this problem, but no actual solutions. How should something of this nature be implemented? Can it just be done by manipulating the output of the program after it is displayed to the user?
Thanks!
So just wrap the prints in pthread_mutex_lock/unlocks with a single pthread_mutex_t and you should be fine.
http://linux.die.net/man/3/pthread_mutex_lock
pthread_mutex_t = PTHREAD_MUTEX_INITIALIZER;
void *listenloop(void *arg){
while (1){
Sleep(2000);
pthread_mutex_lock(&mutex);
puts("testing 123\n");
pthread_mutex_unlock(&mutex);
}
return NULL;
}
int main(){
pthread_t listener;
pthread_create(&listener,NULL,listenloop,"foo");
char testinput[200];
while(1){
pthread_mutex_lock(&mutex);
puts("Scanning: ");
pthread_mutex_unlock(&mutex);
scanf("%s",testinput);
pthread_mutex_lock(&mutex);
puts("\n\n");
printf("You typed: %s: ",testinput);
pthread_mutex_unlock(&mutex);
}
}
In your original code, there should be no "messed up" output (caused by threading, anyway) in that code as only the one thread (the main one) is doing any output.
The only thing the other thread does is infinitely loop with a delay of some sort.
Now that you've updated the question to output from the other thread then, yes, it is possible for the output to intermix.
There are several ways around this, two spring to mind immediately.
Have all output go through a series of functions which mutex-protect the output stream, such as mutexed_printf()/mutexed_puts() (which you'll need to provide) (a).
Do all output from one of the threads, meaning the other will have to send data to it via some means (inter-thread communications like a queue) - that way all output can be properly mixed, such as on newline boundaries.
(a) Also keep in mind that, if you want to mutex protect the output stream for the user input operation, you'll probably want to protect the puts/scanf atomically so that the testing output doesn't mess up your input (by outputting messages after the prompt but before/during your input). That won't be possible with a mutexed_puts() function, you'll need an expanded mutexed_prompt_and_input() one.

How to make processes alternating?

As for threads, I have mutex and conditionals so I could manipulate them easily.
However, if I create two processes by fork(), how could I make them alternating?
Or, is there any way to create a "critical section" for processes?
I intended to make a program that prints "r" and "w" alternatively, here is the code.
#include <stdio.h>
#include <stdlib.h>
int pipe_1[2];
int flag = 0;
void r();
void w();
int main() {
pipe(pipe_1);
if(fork())
r();
else
w();
}
void r() {
int count = 0;
while(1) {
printf("%d \n", flag);
if (count == 10)
exit(0);
if(flag == 0) {
puts("r");
flag = 1;
count++;
while(flag == 1)
;
}
}
}
void w() {
while(1) {
if(flag == 1) {
puts("w");
flag = 0;
while(flag == 0)
;
}
}
}
The out put is only:
0
r
Then it seems to enter a infinite loop.
What's the problem?
And what's the right way to make alternating processes?
Thanks.
This may be overwhelming, but there are TONS of primitives you could use. See here for a list.
http://beej.us/guide/bgipc/output/html/singlepage/bgipc.html
Glancing at the list, just about all of those could be used. Some are more like traditional pthread synchronization primitives, others are higher-level, but can still be used for synchronization.
For example, you could just open a TCP socket between the two and send messages when it's the other side's turn. Maybe with an incrementing number.
Something perhaps more traditional would be semaphores:
http://beej.us/guide/bgipc/output/html/singlepage/bgipc.html#semaphores
Also, this assumes a modern unix-like platform. Windows is likely very different.
It looks like you have a pipe already, so you can use that to have each side send a message to the other after it's done its print. The other side would do a blocking read, then return when the message was sent, do it's print, send a message back, and go back to a blocking read.
They are separate processes, so each has it's own flag; r changing its doesn't affect w's.
In order for two processes to communicate with each other without sharing the same address space (like threads do), they must use Inter-Process Communication means (aka IPC). Some of the IPC mechanisms are: shared memory, semaphore, pipes, sockets, message queues and more. Most of the time, IPC mechanisms are operating system specific. However, many ideas are general enough so it is possible to come up with a portable implementations, which Boost project did as part of Boost.Interprocess library. What I think you should take a look at first is Synchronization Mechanisms section. Note, however, that this is a C++ library. I am not aware of any C library that is as good as Boost.
Hope it helps. Good Luck!

how to run thread in main function infinitely without causing program to terminate

I have a function say void *WorkerThread ( void *ptr).
The function *WorkerThread( void *ptr) has infinite loop which reads and writes continously from Serial Port
example
void *WorkerThread( void *ptr)
{
while(1)
{
// READS AND WRITE from Serial Port USING MUXTEX_LOCK AND MUTEX_UNLOCK
} //while ends
}
The other function I worte is ThreadTest
example
int ThreadTest()
{
pthread_t Worker;
int iret1;
pthread_mutex_init(&stop_mutex, NULL);
if( iret1 = pthread_create(&Worker, NULL, WorkerThread, NULL) == 0)
{
pthread_mutex_lock(&stop_mutex);
stopThread = true;
pthread_mutex_unlock(&stop_mutex);
}
if (stopThread != false)
stopThread = false;
pthread_mutex_destroy(&stop_mutex);
return 0;
}
In main function
I have something like
int main(int argc, char **argv)
{
fd = OpenSerialPort();
if( ConfigurePort(fd) < 0) return 0;
while (true)
{
ThreadTest();
}
return 0;
}
Now, when I run this sort of code with debug statement it runs fine for few hours and then throw message like "can't able to create thread" and application terminates.
Does anyone have an idea where I am making mistakes.
Also if there is way to run ThreadTest in main with using while(true) as I am already using while(1) in ThreadWorker to read and write infinitely.
All comments and criticism are welcome.
Thanks & regards,
SamPrat.
You are creating threads continually and might be hitting the limit on number of threads.
Pthread_create man page says:
EAGAIN Insufficient resources to create another thread, or a system-imposed
limit on the number of threads was encountered. The latter case may
occur in two ways: the RLIMIT_NPROC soft resource limit (set via
setrlimit(2)), which limits the number of process for a real user ID,
was reached; or the kernel's system-wide limit on the number of
threads, /proc/sys/kernel/threads-max, was reached.
You should rethink of the design of your application. Creating an infinite number of threads is not a god design.
[UPDATE]
you are using lock to set an integer variable:
pthread_mutex_lock(&stop_mutex);
stopThread = true;
pthread_mutex_unlock(&stop_mutex);
However, this is not required as setting an int is atomic (on probably all architectures?). You should use a lock when you are doing not-atomic operations, eg: test and set
take_lock ();
if (a != 1)
a = 1
release_lock ();
You create a new thread each time ThreadTest is called, and never destroy these threads. So eventually you (or the OS) run out of thread handles (a limited resource).
Threads consume resources (memory & processing), and you're creating a thread each time your main loop calls ThreadTest(). And resources are finite, while your loop is not, so this will eventually throw a memory allocation error.
You should get rid of the main loop, and make ThreadTest return the newly created thread (pthread_t). Finally, make main wait for the thread termination using pthread_join.
Your pthreads are zombies and consume system resources. For Linux you can use ulimit -s to check your active upper limits -- but they are not infinite either. Use pthread_join() to let a thread finish and release the resources it consumed.
Do you know that select() is able to read from multiple (device) handles ? You can also define a user defined source to stop select(), or a timeout. With this in mind you are able to start one thread and let it sleeping if nothing occurs. If you intent to stop it, you can send a event (or timeout) to break the select() function call.
An additional design concept you have to consider is message queues to share information between your main application and/or pthread. select() is compatible with this technique so you can use one concept for data sources (devices and message queues).
Here a reference to a good pthread reading and the best pthread book available: Programming with POSIX(R) Threads, ISBN-13:978-0201633924
Looks like you've not called pthread_join() which cleans up state after non-detached threads are finished. I'd speculate that you've hit some per process resource limit here as a result.
As others have noted this is not great design though - why not re-use the thread rather than creating a new one on every loop?

Resources