Making this simple code threadsafe - c

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.

Related

How do I discard user input delivered during sleep function?

I'm trying to create a game using the terminal. I ask if the player is ready and then make a countdown with the code down below. The problem is that all input the user makes is added to the next input query the program makes. I'm looking for a way to discard the previous input or block it entirely during this function.
I could do a getchar loop, but that would need user input after the countdown (pressing enter) which I don't want.
void countdown(void){
printf("5\n");
sleep(1);
printf("4\n");
sleep(1);
printf("3\n");
sleep(1);
printf("2\n");
sleep(1);
printf("1\n");
sleep(1);
clearScreen(0); //clears terminal
}
You basically can't; The notion of "discarding user input during a certain amount of time" doesn't really make any sense for standard out- and input, consider the fact that your input might come from a file for instance (the problem here is that 'time' isn't really a concept that exists in any way in the standard in/output routines).
You'd need a terminal API for that, and there's nothing like that in the C standard library, although there are libraries that provide capabilities like that (but you already said you didn't want to use external libraries).
Since you are using a linux environment, you can try using tcflush()
Link to tcflush documentation
Here is a modified example of your code using tcflush. You can uncomment the bottom portion and see that everything entered during the countdown is cleared from the stdio buffer.
#include <termios.h>
#include <stdio.h>
#include <unistd.h>
void main(){
char str[100];
printf("5\n");
sleep(1);
printf("4\n");
sleep(1);
printf("3\n");
sleep(1);
printf("2\n");
sleep(1);
printf("1\n");
sleep(1);
// arguments for tcflush:
// 0 is for stdin
// TCIFLUSH is to flush data received but not read
tcflush(0,TCIFLUSH);
// prove it works by uncommenting this code
// printf("fgets is waiting");
// fgets(str, sizeof(str), stdin);
// printf("%s", str);
// clearScreen(0); //clears terminal
}
One way would be to use a thread for the countdown.
The main code starts the countdown thread, then loops to get an input.
If the input function returns before the thread has terminated, or the wrong reply was entered, ignore the input and repeat the loop.

appending into a file inside thread

I have written the following function to implement two threads in POSIX. Inside each thread, I want to append a line to a test file named "demo.txt" each time the thread runs. But nothing is being written in the file.
My sample code fragment:
#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
FILE *fp;
void * threadFunc1(void * arg)
{
int i;
for(i=1;;i++)
{
printf("%s\n",(char*)arg);
fprintf(fp,"Looping %d time in threadfunc1",i);
sleep(1);
}
}
void * threadFunc2(void * arg)
{
int i;
for(i=1;;i++)
{
printf("%s\n",(char*)arg);
fprintf(fp,"Looping %d time in threadfunc2",i);
sleep(1);
}
}
int main(void)
{
pthread_t thread1;
pthread_t thread2;
fp=fopen("demo.txt","a");
char * message1 = "i am thread 1";
char * message2 = "i am thread 2";
pthread_create(&thread1,NULL,threadFunc1,(void*)message1 );
pthread_create(&thread2,NULL,threadFunc2,(void*)message2 );
pthread_join(thread1,NULL);
pthread_join(thread2,NULL);
fclose(fp);
return 0;
}
Why there isn't anything being written in the file demo.txt? What will I need to correct if anything wrong?
In general, such scenarios necessitate the need for synchronization mechanisms. The approach depends on your architecture and requirement.
You might need to implement mutex or semaphore.
Another possible approach for synchronization could be such that every thread treats the file as shared memory using a memory mapped file.
If your scenario demands more reads than writes, then the best synchronization mechanism can be based on reader-writer-lock as it allows more concurrent reads.
Another approach can be having mechanism to ensure that at any point of time, the threads write different parts of file and do not compete for the same location in file.
You need to add fflush(fp) after fprintf(fp, ...). This forces a write buffered data.
fflush() not needed if you add \n (new line) character at end of your line.

Get User Input without Blocking Endless loop

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++

Multithreaded messages synchronization

I need to print 2 messages each one in each thread in C and synchronize them.
The one thread prints One and the second prints Two.
So my code is something like that
void printOne(void* empty){
while(1) printf("One ");
}
void printTwo(void* empty){
while(1) printf("Two\n");
}
int main(){
pthread_t t_1,t_2;
pthread_create(&t_1, NULL,(void *)&printOne,NULL);
pthread_create(&t_2, NULL,(void *)&printTwo,NULL);
pthread_join(t_1,NULL);
pthread_join(t_2,NULL);
exit(0);
}
The problem is that randomly prints One and Two but not always in that sequence. I would like to make it print always Two after One. I got a bit confused with the join command.
Thanks in advance!
You are confusing some basic concepts about synchronization here. The pthread_join() function will not guarantee synchronization in the way you are thinking. The join is used to synchronize threads after their execution have finished, i.e., after return is called from within your thread. This way, the calling thread will wait for the specified thread to finish its execution, which is exactly what your code is doing. The main thread is waiting for:
First, t_1 to end
Then, t_2 to end
If t_2 ends before t_1, the main thread will still be blocked by t_1, because this order has to be respected. Of course none of them will finish their execution in your code, since both are stuck in an infinite loop (while(1)).
What you are trying to achieve can be done using many techniques. I'd suggest you to use semaphores (if you want to use the POSIX API) or mutex (already implemented in pthread library).
Here's an example of how your code can be changed to get some synchronization:
void printOne(void* empty){
while(1)
{
sem_wait(&s1); //wait for semaphore s1
printf("One ");
sem_post(&s2); //signal semaphore s2
}
}
void printTwo(void* empty){
while(1)
{
sem_wait(&s2); //wait for semaphore s2
printf("Two\n");
sem_post(&s1); //signal semaphore s1
}
}
sem_t s1, s2; //Declare the semaphores globally, so the threads can access them
int main(){
pthread_t t_1,t_2;
sem_init(&s1, 0, 1); //Initialize s1 with 1
sem_init(&s2, 0, 0); //Initialize s2 with 0
pthread_create(&t_1, NULL,(void *)&printOne,NULL);
pthread_create(&t_2, NULL,(void *)&printTwo,NULL);
pthread_join(t_1,NULL);
pthread_join(t_2,NULL);
exit(0);
}
This way, your code guarantees that one message after another are going to be printed to your output:
One
Two
One
Two
...
Why use threads at all if you want it to be synchronous? Just print them sequentially in main().
Otherwise... I guess you could just run one thread after the other. pthread_join makes the program wait for the thread to finish before continuing.
int main(){
pthread_t t_1,t_2;
pthread_create(&t_1, NULL,(void *)&printOne,NULL);
pthread_join(t_1,NULL);
pthread_create(&t_2, NULL,(void *)&printTwo,NULL);
pthread_join(t_2,NULL);
exit(0);
}
You will have to make a breaking condition in your printOne and printTwo functions if you want the threads to actually finish, though...

c multithreading

There's a weird behavior in my threads:
void * foo(void * nic){
printf("foo");
}
void * threadF(void * pointer){
printf("1\n");
pthread_t threadT;
pthread_attr_t attr;
pthread_attr_init (&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_create(&threadT,NULL,&foo,(void*)NULL);
printf("2\n");
while (!feof(stdin)){
int id, in, out;
fscanf(stdin,"%d:%d:%d",&id,&in,&out);
}
}
int main(){
pthread_attr_t attr;
pthread_attr_init (&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_t threadT;
pthread_create(&vlaknoVstupu,&attr,&threadF,(void*)&data);
pthread_join(threadT,NULL);
pthread_attr_destroy (&attr);
}
// I skipped irelevant parts of code...
the thing is that sometimes the output is 12foo, but usually just 12.
Then the function waits for input. I would expect it to be always 12foo. Do anybody know why are my expectations wrong?
Edit: when I type some input like 1:1:1, which results in going through the while cycle again, there is always the foo output.
Printf does not have a thread guarantee. You shouldn't just call two functions on the same thing from different threads unless it's explicitly guaranteed to be safe, either by the writer or because you wrote it yourself.
What you should do is store a buffer of string pointers, and use atomic operations to insert strings into this buffer, then printf all of them every so often, free the memory, set to null, or just use a lock if it's ok to make the child threads wait on the printf call.
What happens is that (on most implementations) stdin and stdout are tied together in one practical buffer. This is to allow something like:
printf("Input: ");
scanf("%d", &integer);
to work nicely, the inputted characters will appear after the printf text.
As soon as your scanf will grab the stdin, this will 'lock' that buffer, also preventing the stdout of your other thread to flush its data to the screen. Note that 'lock'. Does not necessarily mean real thread locks.
If you'd call the program from console, input something like 1:2:3, and hit enter, you'd see that foo will be displayed at the end.
Since there is no join call for thread foo, the program is probably ending before it runs.

Resources