I am trying to build an elevator simulator program and I am getting started with the passenger function. I need to create a thread for each passenger and ask them to input their floor number. I have been able to create the no of passengers (threads) needed and I just need to ask them for their input. But I haven't been able to figure that out
code
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#include <unistd.h>
#define MAX_PASSENGERS 5
#define floor 5
#define NUM_THREAD 6
pthread_mutex_t mymutex = PTHREAD_MUTEX_INITIALIZER; /*Mutex Initializer*/
int dest_floor;
int elevator[floor];
int current_floor;
int no_passengers;
int t, user_input;
void *passengers(void *threadid)
{
// Getting thread ID
long tid;
tid = (long)threadid;
printf("Passenger %d Kindly select your floor number :\n", tid);
scanf("%d\n", &user_input); // Where I ask them for input
// End of Getting ID
pthread_exit(NULL);
}
int main()
{
pthread_t thread[NUM_THREAD];
int th;
for (t = 1; t < NUM_THREAD; t )
{
th = pthread_create(&thread[t], NULL, passengers, (void *)t);
if (th)
{
printf("ERROR Creating Thread\n");
exit(-1);
}
}
pthread_exit(NULL);
}
What I tried:
void *passengers(void *threadid)
{
// Getting thread ID
long tid;
tid = (long)threadid;
printf("Passenger %d Kindly select your floor number :\n", tid);
scanf("%d\n", &user_input); // Where I ask them for input
// End of Getting ID
pthread_exit(NULL);
}
What I was expecting :
Passenger 2 Kindly select your floor number:2
Passenger 3 KIndly select your floor number:4
... and so on
What I got :
Passenger 1 Kindly select your floor number:
Passenger 2 KIndly select your floor number :
Passenger 3 Kindly select your floor number:
Passenger 4 KIndly select your floor number :
Passenger 5 Kindly select your floor number:
2
3
4
5
6
It doesn't allow the user to input a floor number on the prompt, but prints out all the threads and then collects the input.
CodePudding user response:
Threads are.... multi-threaded. Meaning that the execution is concurrent. You can't/shouldn't assume any particular execution order, because that is handled by the OS. As is the context switch between threads which can happen at any moment. The only way to achieve what you want is to stall all other threads while the current one is executing, which would effectively defeat the purpose of using threads to begin with.
I get it that this is just an artificial academic program to learn threads, but real-world programs are rather arranged so that one single thread handles all user input. And as noted in comments, all threads share the same stdin
. So there's not much making sense of this program.
The sensible solution might be to ask for all this info in main() before creating the threads, then pass the floor number as a parameter to the thread. That way you'll also practice parameter passing to threads, which is important to learn. Maybe instead have each thread print "passenger x is waiting on floor y" when it starts?
CodePudding user response:
Here's a version using the mutex that you have already defined, so only one thread at a time is reading stdin
. Please note that also user_input
must be a local variable in passengers()
because otherwise it is shared between threads and that I've fixed printf()
(%ld
for tid
) and added a double cast in pthread_create()
to avoid a gcc warning 'cast to pointer from integer of different size'
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#include <unistd.h>
#include <stdint.h>
#define MAX_PASSENGERS 5
#define floor 5
#define NUM_THREAD 6
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; /*Mutex Initializer*/
int dest_floor;
int elevator[floor];
int current_floor;
int no_passengers;
int t;
void *passengers(void *threadid)
{
// Getting thread ID
long tid;
int user_input;
tid = (long)threadid;
pthread_mutex_lock( &mutex );
printf("Passenger %ld Kindly select your floor number :\n", tid);
scanf("%d", &user_input); // Where I ask them for input
pthread_mutex_unlock( &mutex );
printf( "Passenger %ld selected %d\n", tid, user_input );
// End of Getting ID
pthread_exit(NULL);
}
int main()
{
pthread_t thread[NUM_THREAD];
int th;
for (t = 1; t < NUM_THREAD; t )
{
th = pthread_create(&thread[t], NULL, passengers, (void *)(intptr_t)t);
if (th)
{
printf("ERROR Creating Thread\n");
exit(-1);
}
}
pthread_exit(NULL);
}
Now it looks like that:
Passenger 1 Kindly select your floor number :
9
Passenger 1 selected 9
Passenger 2 Kindly select your floor number :
8
Passenger 2 selected 8
Passenger 4 Kindly select your floor number :
7
Passenger 4 selected 7
Passenger 3 Kindly select your floor number :
6
Passenger 3 selected 6
Passenger 5 Kindly select your floor number :
5
Passenger 5 selected 5