Multithreaded messages synchronization - c

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

Related

Unique semaphore for each thread

I have been assigned a modified version of the "Santa Claus" semaphore problem.
Santa Claus is a thread that randomly wakes up to check how many and what kind of threads are waiting to report to him (Work elves and Collecting elves)
What I have made are work elf and collecting elf threads:
void *collectingElf(void *arg, int semaphoreIndex) {
while (1) {
sem_wait(&elveCountMutex); //semaphore for critical section, the number of elves
printf("\nCollecting! %d\n", (int) pthread_self()); // thread is collecting stuff
sleep((unsigned int) (rand() % 4)); // thread sleeps for a random amount of time
printf("Done collecting! %d\n", (int) pthread_self()); // Print process ID, just for easier tracking
sem_post(&elveCountMutex); // Release the elve count semaphore
sem_wait(&collectingElveSem);
}
}
void *workingElf(void *arg) //same as collecting elf
{
while (1) {
sem_wait(&elveCountMutex);
printf("\nWorking! %d\n", pthread_self());
sleep(1);
workingElveCount++;
printf("Done working! %d\n", pthread_self());
sem_wait(&workElfSem);
sem_post(&elveCountMutex);
}
}
So here the elve counts are protected, since the threads can only access the counters when elveCountMutex is locked. This I can understand and this seems logical. Afterwards the thread should block and wait for Santa to unblock it.
So, from what I read, once semaphore reaches value 0, thread will block. Anything above 0 will not block it, and negative value indicates how many threads are waiting for the semaphore to be unlocked.
So, once the threads running are finished, they decrement the semaphore, and block.
However, what I cannot seem to grasp is this part of the assignment:
For a collecting meeting to start, at least one work elf and three collecting elves are necessary. • If enough elves are present that both meetings could start, the collecting-meeting
always has priority, and all work-elves not needed anymore resume their work.
Say if I have 3 work elves, and I need only 1, how do I release the remaining 2 threads? Do I need a separate semaphore for each thread? Or am I missing something?
Edit: My bad, I completely forgot to tell about the Santa implementation.
Santa wakes up and releases the semaphores, in this way:
void* Santa(void *arg)
{
while (1) {
sleep((unsigned)rand() % 4); //Santa sleeps randomly between 0 and 3 seconds;
sem_wait(&elveCountMutex); //access both elf counters
if(workingElveCount>=2 && collectingElveCount >= 3) //decide which meeting should commence
{
int releaseWorkElveCount = workingElveCount-1;
for(int i = 0;i<releaseWorkElveCount;i++)
{
sem_post(&workElfSem);
}
sleep(5);
collectingMeeting(&collectingMeetingThread); //This just prints that we are in a collecting meeting
pthread_join(collectingMeetingThread,0);
sem_wait(&elveCountMutex);
for(int i=0;i<workingElveCount;i++)
{
sem_post(&workElfSem);
}
for(int i=0;i<collectingElveCount;i++)
{
sem_post(&collectingElveSem);
}
workingElveCount=0;
collectingElveCount=0;
}
}
I do not understand your management of semaphore
In
void *collectingElf(void *arg, int semaphoreIndex) {
while (1) {
...
sem_wait(&collectingElveSem);
}
}
that gets but never releases collectingElveSem, and that in an infinite loop ?
In
void *workingElf(void *arg) //same as collecting elf
{
while (1) {
sem_wait(&elveCountMutex);
...
sem_wait(&workElfSem);
}
}
that get but never release elveCountMutex and workElfSem, and that in an infinite loop. collectingElf also (try to) get elveCountMutex but I will not able to do after one turn in workingElf
If your semaphore are not recursive workingElf will also be blocked after one turn because not able to get again the semaphores. If the semaphore are recursive this cannot be for an infinite deep and workingElf will block itself after enough loops

Conditional Variables with multithreading

I am working on the dining philosophers problem, where n philosophers take turns thinking and eating. I would like to have a version of this where the philosophers will eat in the order of their id: 0,1,2,3,4...,but my threads keep getting blocked. My threads start by calling PhilosopherThread().
void putDownChopsticks(int threadIndex){
//finished eating
pindex++;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&lock);
}
void pickUpChopsticks(int threadIndex){
pthread_mutex_lock(&lock);
while(pindex != threadIndex){
pthread_cond_wait(&cond, &lock);
}
//lets go eat
}
void eating(){
//put thread to sleep
}
void thinking(){
//put thread to sleep
}
void* PhilosopherThread(void *x){
int *index = x;
thinking(); //just puts thread to sleep to simulate thinking
pickUpChopsticks(*index);
eating(); //just puts thread to sleep to simulate eating
putDownChopsticks(*index);
return NULL;
}
I'm having a bit of trouble trying to get the philosophers in order. I can only get the first 2 threads to eat before the threads get blocked.
Edit: as far as i know im doing this right. I first lock the mutex, then I check if pindex is the current thread id, if its not the thread will wait until pindex does equal the id. Then the thread can go eat and once where done, we incread pindex, signal that the thread is done, and unlock the mutex.
This code sometimes works and sometimes does not. First, since you did not provide a complete program, here are the missing bits I used for testing purposes:
#include <stdlib.h>
#include <pthread.h>
static pthread_cond_t cond;
static pthread_mutex_t lock;
static pindex;
/* ... your code ... */
int main () {
int id[5], i;
pthread_t tid[5];
for (i = 0; i < 5; ++i) {
id[i] = i;
pthread_create(tid+i, 0, PhilosopherThread, id+i);
}
for (i = 0; i < 5; ++i) pthread_join(tid[i], 0);
exit(0);
}
The critical piece to notice is how you wake up the next philosopher:
pthread_cond_signal(&cond);
This call will only wake up one thread. But, which thread is at the discretion of the OS. Therefore, if it does not happen to wake up the philosopher that is supposed to wake up, no other philosopher is woken up.
A simple fix would be to wake up all waiting threads instead of just one. The philosophers that don't match will go back to waiting, and the one that is supposed to go next will go.
pthread_cond_broadcast(&cond);
However, since each thread knows which philosopher should wake up, you could change your solution to allow that to happen. One way could be to implement a separate condition variable per philosopher, and use pthread_cond_signal() on the next philosopher's condition variable.

Explanation why conditional variable in C does not work correctly

I want to write a simple multithreaded program making use of conditional variables in C.
I want to have main thread (thread A) which sleeps 5 sec and then wake up waiting clients (therads B, possible many) that print a message. This should be repeated all the time.
I have already read the manual but I don't understand why this does not work.
Let's assume that I have those variables given to all threads via pointers (properly, I have checked that):
pthread_mutex_t* mutex;
pthread_cond_t* cond;
int* variable;
I have the following code:
THREAD A (sleeping):
while(1)
{
lockMutex(mutex);
(*variable) = 1;
pthread_cond_broadcast(cond);
unlockMutex(mutex);
sleep(5);
lockMutex(mutex);
(*variable) = 0;
pthread_cond_broadcast(cond);
unlockMutex(mutex);
}
THREAD B (printing):
while(1)
{
lockMutex(mutex);
while((*variable) == 1)
pthread_cond_wait(cond, mutex);
unlockMutex(mutex);
fprintf("Active thread! Number: %d\n", id);
lockMutex(mutex);
while((*(variable))==0)
pthread_cond_wait(cond, mutex);
unlockMutex(mutex);
}
I don't have deadlock, but unfortunatelly this doesn't work as I expected. Can somebody give me an explanation what should I do? I would be grateful for any help.
The likely problem is that Thread A is immediately setting *variable = 1 before any of the sleeping threads have a chance to see it as 0. Just because the condition variable will wake up waiting threads doesn't mean those woken threads will get scheduled fast enough to prevent Thread A from writing to *variable again.

Thread and Forks

I am relatively new to threads and forks. So to understand them a bit better I have been writing simple programs. One of the little programs I have written two programs, one to print a counter on two processes, and another with two threads.
What I noticed is that the fork prints the counters interlaced while the thread prints one thread's counter and then the others. So the thread is not so parallel, but behaves more serial Why is that? Am I doing something wrong?
Also, what exactly does pthread_join do? Even when I don't do pthread_join the program runs similarly.
Here is my code for the thread
void * thread1(void *a){
int i =0;
for(i=0; i<100; i++)
printf("Thread 1 %d\n",i);
}
void * thread2(void *b){
int i =0;
for(i=0; i<100; i++)
printf("Thread 2 %d\n", i);
}
int main()
{
pthread_t tid1,tid2;
pthread_create(&tid1,NULL,thread1, NULL);
pthread_create(&tid2,NULL,thread2, NULL);
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
return 0;
}
And here is my code for fork
int main(void)
{
pid_t childPID;
childPID = fork();
if(childPID >= 0) // fork was successful
{
if(childPID == 0) // child process
{ int i;
for(i=0; i<100;i++)
printf("\n Child Process Counter : %d\n",i);
}
else //Parent process
{
int i;
for(i=0; i<100;i++)
printf("\n Parent Process Counter : %d\n",i);
}
}
else // fork failed
{
printf("\n Fork failed, quitting!!!!!!\n");
return 1;
}
return 0;
}
EDIT:
How can I make the threaded program behave more like the fork program? i.e. the counter prints interweave.
You are traveling down a bad road here. The lesson you should be learning is to not try and out think the OS scheduler. No matter what you do - processing schedules, priorities, or whatever knobs you turn - you cannot do it reliably.
You have backed your way into discovering the need for synchronization mechanisms - mutexes, semaphores, condition variables, thread barriers, etc. What you want to do is exactly why they exist and what you should use to accomplish your goals.
On your last question, pthread_join reclaims some resources from dead, joinable (i.e.not detached) threads and allows you to inspect any return variable from the expired thread. In your program they are mostly serving as a blocking mechanism. That is, main will block on those calls until the threads expire. Without the pthread_joins your main would end and the process would die, including the threads you created. If you don't want to join the threads and aren't doing anything useful in main then use pthread_exit in main as this will allow main to exit but the threads to continue processing.
First of all, a fork creates a second process while creating a thread creates a "dispatchable unit of work" within the same process.
Getting two different processes to be interleaved is usually a simple matter of letting the OS run. However, within a process you need to know more about how the OS chooses which of several threads to run.
You could probably, artificially, get the output from the threads to be interleaved by calling sleep for different times from each thread. That is, create thread A (code it to output one line, and then sleep for 100) then create thread B (code it to output one line and then sleep for 50, etc.)
I understand wanting to see how threads can run in parallel, similar to processes. But, is this a real requirement or just a "zoo" request?

Output in multi threading program

Writing my basic programs on multi threading and I m coming across several difficulties.
In the program below if I give sleep at position 1 then value of shared data being printed is always 10 while keeping sleep at position 2 the value of shared data is always 0.
Why this kind of output is coming ?
How to decide at which place we should give sleep.
Does this mean that if we are placing a sleep inside the mutex then the other thread is not being executed at all thus the shared data being 0.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include<unistd.h>
pthread_mutex_t lock;
int shared_data = 0;
void * function(void *arg)
{
int i ;
for(i =0; i < 10; i++)
{
pthread_mutex_lock(&lock);
shared_data++;
pthread_mutex_unlock(&lock);
}
pthread_exit(NULL);
}
int main()
{
pthread_t thread;
void * exit_status;
int i;
pthread_mutex_init(&lock, NULL);
i = pthread_create(&thread, NULL, function, NULL);
for(i =0; i < 10; i++)
{
sleep(1); //POSITION 1
pthread_mutex_lock(&lock);
//sleep(1); //POSITION 2
printf("Shared data value is %d\n", shared_data);
pthread_mutex_unlock(&lock);
}
pthread_join(thread, &exit_status);
pthread_mutex_destroy(&lock);
}
When you sleep before you lock the mutex, then you're giving the other thread plenty of time to change the value of the shared variable. That's why you're seeing a value of "10" with the 'sleep' in position #1.
When you grab the mutex first, you're able to lock it fast enough that you can print out the value before the other thread has a chance to modify it. The other thread sits and blocks on the pthread_mutex_lock() call until your main thread has finished sleeping and unlocked it. At that point, the second thread finally gets to run and alter the value. That's why you're seeing a value of "0" with the 'sleep' at position #2.
This is a classic case of a race condition. On a different machine, the same code might not display "0" with the sleep call at position #2. It's entirely possible that the second thread has the opportunity to alter the value of the variable once or twice before your main thread locks the mutex. A mutex can ensure that two threads don't access the same variable at the same time, but it doesn't have any control over the order in which the two threads access it.
I had a full explanation here but ended up deleting it. This is a basic synchronization problem and you should be able to trace and identify it before tackling anything more complicated.
But I'll give you a hint: It's only the sleep() in position 1 that matters; the other one inside the lock is irrelevant as long as it doesn't change the code outside the lock.

Resources