I'm facing simple issue with Semaphore's task.
I am having N-processes (P1, P2, P3, P4...Pn). No matter in what order I create threads, I need them to execute in exact order (P1, P2, P3, P4...Pn). I need to come with solution, where I use minimum semaphores required.
It would be quite simple using Mutex, but the task says "use only semaphores".
I'm using only one semaphore. In while, within the condition, if order number is NOT equals your ID number, just unlock semaphore and cycle in while, till order number is equals to your ID number.
I think that problem might be with "Spurious wakeups".
Here is my code:
sem_t semvar;
int order = 0;
void *sayHello(void *thread_id){
int *my_id = (int *) thread_id;
while(1)
{
// take semaphore and close critical zone to read order variable to recognize who's on turn!
sem_wait(&semvar);
if(*my_id == order)
{
// if I'm on turn, then I shout my number and set order variable to someone behind me
printf("I'm thread no.: %d\n", *my_id);
order++;
break;
}
// release semaphore if I'm not on turn!
sem_post(&semvar);
}
// release semaphore if it was my turn, I shout my number and gonna end (die)!
sem_post(&semvar);
pthread_exit(NULL);
}
int main(int argc, char *argv[]) {
int numbOfThreads = 13;
int *thread_id[numbOfThreads];
int new_thread, i;
pthread_t threads[numbOfThreads];
// generating thread numbers --> NOTE: you need this, if you use random thread generating!!!
for(i = 0; i < numbOfThreads; i++)
{
thread_id[i] = (int *) malloc(sizeof(int));
*thread_id[i] = i;
}
// random thread generating for testing to make sure it works
pthread_create(&threads[10], NULL, sayHello, (void *) thread_id[10]);
pthread_create(&threads[12], NULL, sayHello, (void *) thread_id[12]);
pthread_create(&threads[8], NULL, sayHello, (void *) thread_id[8]);
pthread_create(&threads[3], NULL, sayHello, (void *) thread_id[3]);
pthread_create(&threads[5], NULL, sayHello, (void *) thread_id[5]);
pthread_create(&threads[1], NULL, sayHello, (void *) thread_id[1]);
pthread_create(&threads[0], NULL, sayHello, (void *) thread_id[0]);
pthread_create(&threads[4], NULL, sayHello, (void *) thread_id[4]);
pthread_create(&threads[7], NULL, sayHello, (void *) thread_id[7]);
pthread_create(&threads[6], NULL, sayHello, (void *) thread_id[6]);
pthread_create(&threads[2], NULL, sayHello, (void *) thread_id[2]);
pthread_create(&threads[9], NULL, sayHello, (void *) thread_id[9]);
pthread_create(&threads[11], NULL, sayHello, (void *) thread_id[11]);
/*
// automatic thread generating
for(i = 0; i < numbOfThreads; i++)
{
thread_id[i] = (int *) malloc(sizeof(int));
*thread_id[i] = i;
new_thread = pthread_create(&threads[i], NULL, sayHello, (void *) thread_id[i]);
if(new_thread)
{
printf("Error has occured");
exit(-1);
}
}
*/
// do not end main function before all the threads are done with work!
for(i = 0; i < numbOfThreads; i++)
{
pthread_join( threads[i], NULL);
}
printf("All the threads are gone!");
return 1;
}
Related
So I have a scaled down version of an elevator program that uses pthreads in c. Each thread is an individual lift that calls function request(). I am not sure how to know which lift (1, 2 or 3) which are threads are using the function request. In the request function I need to print which thread used it at that time. Sorry if my explanation doesn't make complete sense.
void* request(void* abc)
{
int ii;
for(ii = 0; ii < 8; ii++)
{
sleep(1);
printf("REQUEST FROM LIFT COMPLETED\n");
}
}
int main()
{
pthread_t lift1;
pthread_t lift2;
pthread_t lift3;
pthread_create(&lift1, NULL, request, NULL);
pthread_create(&lift2, NULL, request, NULL);
pthread_create(&lift3, NULL, request, NULL);
pthread_join(lift1, NULL);
pthread_join(lift1, NULL);
pthread_join(lift1, NULL);
return 0;
}
You could do this in multiple ways, the simplest one is to pass some meaningful value as thread parameter to identify each thread.
Here's an example:
void *request(void *data)
{
const int id = *(const int *)data;
int ii;
for(ii = 0; ii < 8; ii++)
{
sleep(1);
printf("REQUEST FROM LIFT %d COMPLETED\n", id);
}
}
int main()
{
const int id1 = 1, id2 = 2, id3 = 3;
pthread_t lift1;
pthread_t lift2;
pthread_t lift3;
pthread_create(&lift1, NULL, request, (void *)&id1);
pthread_create(&lift2, NULL, request, (void *)&id2);
pthread_create(&lift3, NULL, request, (void *)&id3);
pthread_join(lift1, NULL);
pthread_join(lift2, NULL);
pthread_join(lift3, NULL);
return 0;
}
You could also define those id varibles as static globals:
// Outside main:
static const int id1 = 1, id2 = 2, id3 = 3;
For faster calculation, trying to make my method parallelized by 4 threads. Where threads are making 4 separate calculation whether I was expecting concurrent operation and on single variable.
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
static int x, j=5;
void *print_count (void *dummy)
{
for(int i=0;i<1000;i++){
x+=j;
}
}
int main ()
{
pthread_t p1, p2, p3, p4;
pthread_create (&p1, NULL, print_count, NULL);
pthread_create (&p2, NULL, print_count, NULL);
pthread_create (&p3, NULL, print_count, NULL);
pthread_create (&p4, NULL, print_count, NULL);
pthread_join (p1, NULL);
pthread_join (p2, NULL);
pthread_join (p3, NULL);
pthread_join (p4, NULL);
printf("Actual output: %d \nExpected output: 5000\n", x);
return 0;
}
I expect the output 5000 as the increment is 5 and loop for 1000 times.
But the actual output first of all not static, it always change and it is near 4 times of 5000 because threads are calculating the print_count separately.
Thank you
If you are under C11 you can use _Atomic
Of course each thread needs to work over a range of values (not with the complete set), pass a struct:
#include <stdio.h>
#include <stdatomic.h>
#include <pthread.h>
_Atomic int x;
static int j = 5;
struct range {
int from, to;
};
void *print_count(void *data)
{
struct range *range = data;
for (int i = range->from; i < range->to; i++) {
x += j;
}
return NULL;
}
int main(void)
{
pthread_t p1, p2, p3, p4;
struct range ranges[] = {
{0, 250},
{250, 500},
{500, 750},
{750, 1000}
};
pthread_create(&p1, NULL, print_count, &ranges[0]);
pthread_create(&p2, NULL, print_count, &ranges[1]);
pthread_create(&p3, NULL, print_count, &ranges[2]);
pthread_create(&p4, NULL, print_count, &ranges[3]);
pthread_join(p1, NULL);
pthread_join(p2, NULL);
pthread_join(p3, NULL);
pthread_join(p4, NULL);
printf("Actual output: %d \nExpected output: 5000\n", x);
return 0;
}
Or a compound literal:
pthread_create(&p1, NULL, print_count, (int []){ 0, 250});
pthread_create(&p2, NULL, print_count, (int []){250, 500});
pthread_create(&p3, NULL, print_count, (int []){500, 750});
pthread_create(&p4, NULL, print_count, (int []){750, 1000});
...
void *print_count(void *data)
{
int *range = data;
for (int i = range[0]; i < range[1]; i++) {
x += j;
}
return NULL;
}
in order to divide the task.
Output:
Actual output: 5000
Expected output: 5000
I want to run Pthreads in c. i am comfortable with sending integer values to Pthread in c. But when I am passing the data structure to the thread, it is printing garbage values.
My code is as follows:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NUMBER_OF_THREADS 3
typedef struct MyStructure
{
int id;
char *myName;
}myst;
void *PrintHello(void *threadArgs)
{
myst *myPersonalSt;
myPersonalSt = (myst *) threadArgs;
printf("Thread %d and Name : %s \n", myPersonalSt->id ,
myPersonalSt->myName);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_t threads[NUMBER_OF_THREADS];
long taskids[NUMBER_OF_THREADS];
int rc, t;
char myNameArray[NUMBER_OF_THREADS][100] = {"kp" , "kkp" , "ap"};
myst **mystArray;
mystArray = (myst **)malloc(NUMBER_OF_THREADS*sizeof(myst));
for(t=0;t<NUMBER_OF_THREADS;t++)
{
mystArray[t] = (myst *)calloc(1,sizeof(myst));
mystArray[t]->id = t+1;
mystArray[t]->myName = myNameArray[t];
}
for(t=0;t<NUMBER_OF_THREADS;t++) {
printf("Creating thread %d\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello,
(void *) mystArray);
if (rc) {
printf("ERROR; return code from
pthread_create() is %d\n", rc);
exit(-1);
}
}
for(t=0;t<NUMBER_OF_THREADS;t++) {
pthread_join(threads[t],NULL);
}
pthread_exit(NULL); // this takes an input parameter !
}
I was thinking that it was a problem with MALLOC (because it doesn't initialize memory allocated). So I used CALLOC , but the same problem occured.
rc = pthread_create(&threads[t], NULL, PrintHello,
(void *) mystArray);
You're missing the array index here, you mean mystArray + t.
On a side note: remove all these casts, they make the code hard to read. void * is generic and implicitly convertible in c.
This line is wrong:
rc = pthread_create(&threads[t], NULL, PrintHello,
(void *) mystArray);
Given how you're written the rest of the code, it should be:
rc = pthread_create(&threads[t], NULL, PrintHello,
(void *) ( mystArray[t] ) );
But the use of malloc()/calloc() is unnecessary:
myst mystArray[ NUMBER_OF_THREADS ];
memset( mystArray, 0, sizeof( mystArray ) );
...
rc = pthread_create(&threads[t], NULL, PrintHello,
(void *) &( mystArray[t] ) );
That will work without the malloc()/calloc().
I'm trying to pass an array to thread function so that it has access to the array in the function. For the moment it just contains the name of the threads.
const char *a[2];
char *s = "Thread 1";
char *r = "Thread 2";
a[0] = s;
a[1] = r;
pthread_create(&t, NULL, oddhandler, (void *)a[0]);
pthread_create(&y, NULL, evenhandler, (void *)a[1]);
The intention is to write the create like this
pthread_create(&t, NULL, oddhandler, &a);
pthread_create(&y, NULL, evenhandler, &a);
How would I re-write this function to accommodate this change?
static void *
oddhandler(void *p)
{
char *q = (char *)p;
printf("%s is ready.\n", q);
sigset_t set;
int sig = SIGUSR1;
sigemptyset(&set);
sigaddset(&set, SIGUSR1);
while (1) {
/* Wait for SIGUSR1 */
sigwait(&set, &sig);
printf("%s received a SIGUSR1!\n", q);
}
return ((void *)NULL);
}
You could try coupling the thread id with the thread data :
typedef struct thread_info {
int thread_id; // different for every thread
void * thread_data; // the same for every thread
}
As in your example program, you could create one function, handler, and have threads adjust based on their id.
pthread_create(&(t[id], NULL, handler, &(info[i]));
void * handler(void * info) {
thread_info * myInfo = (thread_info *) info;
char *q = ((char *) myInfo->thread_data) + myInfo->thread_id;
// rest of function
}
In the following code:
int main (int argc, const char * argv[]) {
// insert code here...
pthread_t t1, t2;
int sp1, sp2;
sp1 = pthread_create( &t1, NULL, getScalarProduct, NULL);
sp2 = pthread_create( &t2, NULL, getScalarProduct, NULL);
pthread_join( t1, NULL);
pthread_join( t2, NULL);
printf("Seperate scalars: %d %d\n", sp1, sp2);
finalScalarProd = sp1 + sp2;
printf("Result: %d\n", finalScalarProd);
return 0;
}
I've been unable to get anything back other than zero for the finalScalarProduct, and both sp1 and sp2 are zero also. I believe it's something to do with the NULL argument being passed in pthread_join. I don't really understand what this argument is for.
Any help appreciated!
That's because pthread_create returns zero upon success.
The value is not the result of the main thread function, but the result of the thread creation (that might fail in some cases).
void * threadMainFunc(void * arg) {
// modify arg like this
int * ip = (int *)arg;
*ip = 3; // this is the "return value"
return NULL;
}
pthread_create( &t1, NULL, threadMainFunc, &sp1);