I have a simple program below where it prints the thread id of each thread created.
#include <stdio.h>
#include <pthread.h>
#define NUM_THREAD 5
void *runner(void *param);
int main()
{
int i;
pthread_t tid[NUM_THREAD];
for(i = 0; i < NUM_THREAD; i++){
pthread_create(&tid[i], NULL, runner, NULL);
printf("%u\n", (unsigned int) pthread_self());
}
// for(i = 0; i < NUM_THREAD; i++)
// pthread_join(tid[i], NULL);
}
void *runner(void *param)
{
/* do some work */
pthread_exit(0);
}
The code is running fine and giving me the right output.
1527895872
1527895872
1527895872
1527895872
1527895872
My question is why are the thread ids the same?
Because you are printing the thread id of main(), instead of the thread itself. You need to move the printf() to the code that runs as a thread i.e. runner().
#include <stdio.h>
#include <pthread.h>
#define NUM_THREAD 5
void *runner(void *param);
int main()
{
int i;
pthread_t tid[NUM_THREAD];
for(i = 0; i < NUM_THREAD; i++){
pthread_create(&tid[i], NULL, runner, NULL);
// printf("%u\n", (unsigned int) pthread_self()); // <----- from here
}
// for(i = 0; i < NUM_THREAD; i++)
// pthread_join(tid[i], NULL);
}
void *runner(void *param)
{
printf("%u\n", (unsigned int) pthread_self()); // <-------- to here
/* do some work */
pthread_exit(0);
}
It is printing the id of the calling thread - http://man7.org/linux/man-pages/man3/pthread_self.3.html - this is the same thread each time in the loop;
Perhaps the printf should be moved to runner
Related
I want to Interpret how to reach this output for at least 5 different outputs.
And Modify the program to fix this problem.How Can I do it?
#include <stdio.h>
#include <pthread.h>
#define NUM_THREADS 4
void *threadFunc(void *pArg)
{
int *p = (int*)pArg;
int myNum = *p;
printf("Thread number %d\n", myNum);
return 0;
}
int main(void)
{
int i;
pthread_t tid [NUM_THREADS];
for(i = 0; i < NUM_THREADS; i++)
{
pthread_create(&tid[i], NULL, threadFunc, &i);
}
for(i = 0; i < NUM_THREADS; i++)
{
pthread_join(tid [i], NULL);
}
return 0;
}
Thread function receives pointer to int. Memory it points to is shared between threads, so while thread function reads value of i it is changed by main thread. This is race condition.
You can fix it by storing individual i values for each thread:
#include <stdio.h>
#include <pthread.h>
#define NUM_THREADS 4
void *threadFunc(void *pArg)
{
int *p = (int*)pArg;
int myNum = *p;
printf("Thread number %d\n", myNum);
return NULL; // thread function returns a pointer
}
int main(void)
{
int i;
pthread_t tid[NUM_THREADS];
int data[NUM_THREADS];
for (i = 0; i < NUM_THREADS; i++)
{
data[i] = i;
pthread_create(&tid[i], NULL, threadFunc, data+i); // `data+i` is equivalent to `&data[i]`
}
for (i = 0; i < NUM_THREADS; i++)
{
pthread_join(tid [i], NULL);
}
return 0;
}
Another option is to pass an integer as a pointer value. It doesn't require storage for each thread but may cause truncating problems because of int<->intptr_t conversion.
#include <stdio.h>
#include <pthread.h>
#include <inttypes.h> // for intptr_t
#define NUM_THREADS 4
void *threadFunc(void *arg)
{
int myNum = (intptr_t)arg;
printf("Thread number %d\n", myNum);
return NULL; // thread function returns a pointer
}
int main(void)
{
int i;
pthread_t tid[NUM_THREADS];
for (i = 0; i < NUM_THREADS; i++)
{
pthread_create(&tid[i], NULL, threadFunc, (void *)(intptr_t)i);
}
for (i = 0; i < NUM_THREADS; i++)
{
pthread_join(tid [i], NULL);
}
return 0;
}
#include <stdio.h>
#include <pthread.h>
void *runner(void * p)
{
int *line = p;
printf("line: %d\n", *line);
}
int main()
{
pthread_t tid[2];
for (int i = 0; i < 2; i++)
pthread_create(&tid[i], 0, runner, &i);
for (int i = 0; i < 2; i++)
pthread_join(tid[i], NULL);
return 0;
}
For the above code I expect the output to be
line 0
line 1
But the output is actually
line 1
line 2
So what is wrong with this code? How did i get incremented? Do I have to pass structs to the runner function?
There's no guarantee that printf("line: %d\n", *line); line will finish before pthread_create returns, which means you have a race on i.
(The main thread tries to increment it and the new threads try to read it
via their argument pointer).
You can solve the problem by passing pointers to different objects (one per thread, optimally cache-aligned, but that hardly matters here):
#include <stdio.h>
#include <pthread.h>
void *runner(void * p)
{
int *line = p;
printf("line: %d\n", *line);
return 0;
}
int main()
{
pthread_t tid[2];
int ints[2];
for (int i = 0; i < 2; i++){
ints[i]=i;
if(pthread_create(&tid[i], 0, runner, &ints[i])) return 1;
}
for (int i = 0; i < 2; i++)
pthread_join(tid[i], NULL);
return 0;
}
or by passing the i by value (by casting it to void*):
#include <stdio.h>
#include <pthread.h>
#include <stdint.h>
void *runner(void * p)
{
printf("line: %d\n", (int)(intptr_t)p);
return 0;
}
int main()
{
pthread_t tid[2];
int ints[2];
for (int i = 0; i < 2; i++){
if(pthread_create(&tid[i], 0, runner, (void*)(intptr_t)i)) return 1;
}
for (int i = 0; i < 2; i++)
pthread_join(tid[i], NULL);
return 0;
}
Need a solution that creates 5 pthreads. Each pthread executes a function that involves iterating through a loop 10 times. In each iteration of the loop, a thread increments an int from 0 to 0.9*MAX_INT and then prints the iteration number. Make sure that each of the 5 threads finish the ith iteration of the loop before they can start the (i+1)th iteration (i.e. all threads synchronize/rendezvous towards the end of each iteration). I need to use a two-phase barrier implemented using POSIX semaphores to enforce the synchronization constraint
I wrote following code am I correct ?
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int thread_count;
void* MyThread(void* rank);
int main()
{
long thread;
pthread_t* thread_handles;
thread_count = 5;
thread_handles = malloc (thread_count*sizeof(pthread_t));
for (thread = 0; thread < thread_count; thread++)
pthread_create(&thread_handles[thread],NULL,MyThread,(void*) thread);
for (thread = 0; thread < thread_count; thread++)
pthread_join(thread_handles[thread], NULL);
free(thread_handles);
return 0;
}
void* Hello(void* rank)
{
long my_rank = (long) rank;
int a,i;
a=0;
for(i=0;i<10;i++)
{
int n = 5;
int count = 0;
pthread_mutex_t mutex = Semaphore(1)
barrier = Semaphore(0)
a = a + 0.9*MAX_INT;
printf("this is %d iteration\n",i);
mutex.wait()
count = count + 1
mutex.signal()
if count == n: barrier.signal() # unblock ONE thread
barrier.wait()
barrier.signal()
}
}
Edit:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <semaphore.h>
typedef struct {
int n;
int count;
sem_t mutex;
sem_t turnstyle;
sem_t turnstyle2;
} barrier_t;
void init_barrier(barrier_t *barrier, int n)
{
barrier->n = n;
barrier->count = 0;
sem_init(&barrier->mutex, 0, 1);
sem_init(&barrier->turnstyle, 0, 0);
sem_init(&barrier->turnstyle2, 0, 0);
}
void phase1_barrier(barrier_t *barrier)
{
sem_wait(&barrier->mutex);
if (++barrier->count == barrier->n) {
int i;
for (i = 0; i < barrier->n; i++) {
sem_post(&barrier->turnstyle);
}
}
sem_post(&barrier->mutex);
sem_wait(&barrier->turnstyle);
}
void phase2_barrier(barrier_t *barrier)
{
sem_wait(&barrier->mutex);
if (--barrier->count == 0) {
int i;
for (i = 0; i < barrier->n; i++) {
sem_post(&barrier->turnstyle2);
}
}
sem_post(&barrier->mutex);
sem_wait(&barrier->turnstyle2);
}
void wait_barrier(barrier_t *barrier)
{
phase1_barrier(barrier);
phase2_barrier(barrier);
}
#define NUM_THREADS 5
void *myThread(void *);
int main(int argc, char **argv)
{
pthread_t threads[NUM_THREADS];
barrier_t barrier;
int i;
init_barrier(&barrier, NUM_THREADS);
for (i = 0; i < NUM_THREADS; i++) {
pthread_create(&threads[i], NULL, myThread, &barrier);
}
for (i = 0; i < NUM_THREADS, i++) {
pthread_join(threads[i], NULL);
}
return 0;
}
void *myThread(void *arg)
{
barrier_t *barrier = arg;
int i,a;
for(i=0;i<10;i++)
{
a = a + 0.9*MAX_INT;
printf("this is %d iteration\n",i);
}
return NULL;
}
OK, if we examine the Barrier object in, "The Little Book of Semaphores", section 3.7.7, we see that we need a mutex and 2 semaphores called turnstile and turnstile2 (a mutex can be a semaphore that is initialized to 1).
Since we have to use POSIX semaphores, pthreads, and INT_MAX, we start by including the requisite header files:
#include <pthread.h>
#include <semaphore.h>
#include <limits.h>
The book makes the Barrier an object; however, in C, we don't really have objects, but we can create a struct with some functions to operate on it:
typedef struct {
int n;
int count;
sem_t mutex;
sem_t turnstile;
sem_t turnstile2;
} barrier_t;
We can create a function to initialize a barrier:
void init_barrier(barrier_t *barrier, int n)
{
barrier->n = n;
barrier->count = 0;
sem_init(&barrier->mutex, 0, 1);
sem_init(&barrier->turnstile, 0, 0);
sem_init(&barrier->turnstile2, 0, 0);
}
And implement the phase1 function, as in the book:
void phase1_barrier(barrier_t *barrier)
{
sem_wait(&barrier->mutex);
if (++barrier->count == barrier->n) {
int i;
for (i = 0; i < barrier->n; i++) {
sem_post(&barrier->turnstile);
}
}
sem_post(&barrier->mutex);
sem_wait(&barrier->turnstile);
}
Note that the sem_post function only posts a single time, so a loop is required to post the turnstile n times.
The phase2 function also follows directly in the same manner:
void phase2_barrier(barrier_t *barrier)
{
sem_wait(&barrier->mutex);
if (--barrier->count == 0) {
int i;
for (i = 0; i < barrier->n; i++) {
sem_post(&barrier->turnstile2);
}
}
sem_post(&barrier->mutex);
sem_wait(&barrier->turnstile2);
}
Finally, we can implement the wait function:
void wait_barrier(barrier_t *barrier)
{
phase1_barrier(barrier);
phase2_barrier(barrier);
}
Now, in your main function, you can allocate and initialize a barrier and pass it to your spawned threads:
#define NUM_THREADS 5
void *myThread(void *);
int main(int argc, char **argv)
{
pthread_t threads[NUM_THREADS];
barrier_t barrier;
int i;
init_barrier(&barrier, NUM_THREADS);
for (i = 0; i < NUM_THREADS; i++) {
pthread_create(&threads[i], NULL, myThread, &barrier);
}
for (i = 0; i < NUM_THREADS, i++) {
pthread_join(threads[i], NULL);
}
return 0;
}
And finally, implement the thread:
void *myThread(void *arg)
{
barrier_t *barrier = arg;
int i;
int a;
for (i = 0; i < 10; i++) {
for (a = 0; a < 0.9*INT_MAX; a++);
printf("this is %d iteration\n", i);
wait_barrier(barrier);
}
return NULL;
}
I have got a project from my university for critical section problem of n processes. I have made a code for 2 processes in c But I could not figure out how to get it working for n process . The code is in C for linux threads.
Here is code for 2 Processes.
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
int flag[2];
int turn;
const int MAX = 1e9;
int ans = 0;
void lock_init(){
flag[0]=flag[1]=0;
turn = 0;
}
void lock(int self){
flag[self]=1;
turn = 1-self;
while(flag[1-self]==1 && turn == 1-self);
}
void unlock(int self){
flag[self]=0;
}
void* func(void *s){
int i=0;
int *limitptr = (int*) s;
int self = *limitptr;
printf("Thread %d in queue for critical section\n",self);
lock(self);
printf("Thread %d in critical section\n",self);
for(i=0;i<MAX;i++){
ans++;
}
printf("Thread %d done counting\n",self);
printf("Thread %d is exiting critical section\n",self);
unlock(self);
}
int main(){
pthread_t p1, p2;
int a=0,b=1;
lock_init();
pthread_create(&p1, NULL, func, &a);
pthread_create(&p2, NULL, func, &b);
pthread_join(p1, NULL);
pthread_join(p2, NULL);
printf("Exiting Main\n");
return 0;
}
Any help would be appreciated.
Thank You. :)
use a mutex
#include <pthread.h>
declare the mutex like so:
pthread_mutex_t myMutex = PTHREAD_MUTEX_INITIALIZER;
then at the beginning of a critical section call:
pthread_mutex_lock( &myMutex );
and at the end of the critical section call:
pthread_mutex_unlock( &myMutex );
it does not matter how many threads are using that critical section, only one thread will be able to access it at a time
Thank You for your valuable time and answers.
I Found A solution for My problem and thought of sharing it.I Implemented Bakery Algorithm In C.
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
int N;
int global = 10;
int entering[100];
int number[100];
int max(int number[100]) {
int i = 0;
int maximum = number[0];
for (i = 0; i < N; i++) {
if (maximum < number[i])
maximum = number[i];
}
return maximum;
}
void lock(int i) {
int j = 0;
entering[i] = TRUE;
number[i] = 1 + max(number);
entering[i] = FALSE;
for (j = 0; j < N; j++) {
while (entering[j]);
while (number[j] != 0 && (number[j] < number[i] || (number[i] == number[j]) && j < i)) {}
}
}
void unlock(int i) {
number[i] = 0;
}
void *fn(void *integer) {
int i = (int) integer;
lock(i);
printf("\n\n-----------Process %d---------",i);
printf("\nProcess %d is Entering Critical Section\n",i);
global++;
printf("%d is the value of global \n",global);
printf("Process %d is leaving Critical Section\n",i);
printf("----------------------------------\n\n");
unlock(i);
}
int main()
{
printf("Enter Number of Process\n");
scanf("%d",&N);
int th[N];
void *fn(void *);
pthread_t thread[N];
int i = 0;
for (i = 0; i < N; i++) {
th[i] = pthread_create(&thread[i], NULL, fn, (void *)i);
pthread_join(thread[i], NULL);
}
return EXIT_SUCCESS;
}
Again Thank You :)
I am a beginner in C programming and I am trying to perform mutex on the program below, but I'm not getting the proper output.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define NUM_THREAD 4
void *func(void *p);
int counter=0,a=2;
pthread_mutex_t mutexsum = PTHREAD_MUTEX_INITIALIZER;
main()
{
int i,rc;
pthread_t threadid[NUM_THREAD];
for(i = 0; i< NUM_THREAD; i++)
{
a = a + i;
printf("Value of a is %d\n",a);
rc = pthread_create(&threadid[i],NULL,func,(void *)a);
if(rc)
{
printf("Error in thred creation thread[%d] %d",i,rc);
}
}
for(i = 0; i< NUM_THREAD; i++)
{
pthread_join(threadid[i],NULL);
}
printf("Final value of counter is %d\n",counter);
pthread_exit(NULL);
}
void *func(void *p)
{
int i;
i = (int) p;
pthread_mutex_lock(&mutexsum);
counter = counter+a;
printf("%d\n",counter);
pthread_mutex_unlock(&mutexsum);
pthread_exit(NULL);
}
As per the above program and my understanding, the desired output will be 18, but it's giving 32.
func uses a to increment. I'm guessing you meant to increment by i. As it is, by the time each thread runs, a must be at its final value of 8, so you are adding 8 to counter four times.
You are not using i in your thread function, but a.