I'm tryng to implement following reader-writer problem with reader priority ,So first of all, all the reader threads should execute then remaining writer threads.
#include<omp.h>
#include<semaphore.h>
#include<stdio.h>
#include<unistd.h>
int var=10;
int ReadCount=0;
sem_t Sem;
void main()
{
sem_init(&Sem, 0, 1);
int ThreadId = 0;
int NReader, NWriter;
int i,j;
printf("\nEnter number of readers: ");
scanf("%d",&NReader);
printf("\nEnter number of writers: ");
scanf("%d",&NWriter);
#pragma omp parallel num_threads( (NReader+NWriter) ) shared(ThreadId) /*specifies threadId variable is shared
among all the threads*/
{
printf("\n in parallel construct");
#pragma omp for nowait
for(i=0 ; i<NReader ; i++)
{
printf("\nReader started %d",i);
//sleep(5);
#pragma omp critical
{
ReadCount++;
if(ReadCount==1)
sem_wait(&Sem);
}
ThreadId = omp_get_thread_num();
printf("\n\nReader %d with thread id %d is reading shared variable %d ",i,ThreadId,var);
#pragma omp critical
{
ReadCount--;
if(ReadCount==0)
sem_post(&Sem);
}
// sleep(5);
}
#pragma omp for nowait
for(j=0 ; j<NWriter ; j++)
{
printf("\nWriter started %d",j);
sem_wait(&Sem);
sleep(1);
var=var+2;
ThreadId = omp_get_thread_num();
printf("\nWriter %d with ThreadId %d has updated the shared variable to %d ",j,ThreadId,var);
sem_post(&Sem);
}
}
//end of parallel construct
}
But In output always some writer thread is executing in between . I dont know why it is ocurring ? Please anyone suggest me solution to it.
OUTPUT:
[eshwar#localhost ~]$ gcc -fopenmp readwrit.c
[eshwar#localhost ~]$ ./a.out
Enter number of readers: 3
Enter number of writers: 2
in parallel construct
Reader started 0
Reader 0 with thread id 0 is reading shared variable 10
Writer started 0
in parallel construct
in parallel construct
in parallel construct
Reader started 2
in parallel construct
Reader started 1
Writer 0 with ThreadId 0 has updated the shared variable to 12
Reader 2 with thread id 2 is reading shared variable 12
Reader 1 with thread id 1 is reading shared variable 12
Writer started 1
Writer 1 with ThreadId 1 has updated the shared variable to 14 [eshwar#localhost ~]$
I have a code which solves your problem
#include<stdio.h>
#include <time.h>
#include <unistd.h>
#include <omp.h>
int main()
{
int i=0,NumberofReaderThread=0,NumberofWriterThread;
omp_lock_t writelock;
omp_init_lock(&writelock);
int readCount=0;
printf("\nEnter number of Readers thread(MAX 10)");
scanf("%d",&NumberofReaderThread);
printf("\nEnter number of Writers thread(MAX 10)");
scanf("%d",&NumberofWriterThread);
int tid=0;
#pragma omp parallel
#pragma omp for
for(i=0;i<NumberofReaderThread;i++)
{
// time_t rawtime;
//struct tm * timeinfo;
// time ( &rawtime );
//timeinfo = localtime ( &rawtime );
//printf ( "Current local time and date: %s", asctime (timeinfo) );
//sleep(2);
printf("\nReader %d is trying to enter into the Database for reading the data",i);
omp_set_lock(&writelock);
readCount++;
if(readCount==1)
{
printf("\nReader %d is reading the database",i);
}
omp_unset_lock(&writelock);
readCount--;
if(readCount==0)
{
printf("\nReader %d is leaving the database",i);
}
}
#pragma omp parallel shared(tid)// Specifies that one or more variables should be shared among all threads.
#pragma omp for nowait //If there are multiple independent loops within a parallel region
for(i=0;i<NumberofWriterThread;i++)
{
printf("\nWriter %d is trying to enter into database for modifying the data",i);
omp_set_lock(&writelock);
printf("\nWriter %d is writting into the database",i);
printf("\nWriter %d is leaving the database",i);
omp_unset_lock(&writelock);
}
omp_destroy_lock(&writelock);
return 0;
}
But this is done using lock mechanism . You can find similar steps for semaphores too.
Related
I have a use case where I want to run two functions in parallel: the first one contains work that I want to execute in thread 0, and the other contains a "for" loop that I want to share among the remaining 3 threads.
my code is like:
void fct1(){
//do some work1
};
void fct2(){
int p;
#pragma omp for schedule(static)
for (p=start; p < end; p++) {
//do some work2
}
};
int main(){
#pragma omp parallel
{
int tid = omp_get_thread_num();
if (tid==0)
fct1();
if(tid!=0)
fct2();
}
return 0;
}
the problem is that the "omp for" in fct2 hangs because it also waits for thread 0 to execute its part.
Do you have any suggestions?
Thank you.
You can do that with a single (or master if you really want thread 0) pragma. The nowait directive will allow other threads to continue running.
You should use a dynamic scheduling in your for loop as it deals better with a variable number of threads. And if thread 0 has finished its work, it will join the pool.
#include <stdio.h>
#include <omp.h>
#define end 2000
void fct1(){
printf("Hey I am thread %d\n", omp_get_thread_num());
};
void fct2(){
int p;
# pragma omp for schedule(dynamic,128) // adapt chunk size to your problem
for (p=0; p < end; p++) {
printf("%d (%d)\t",p,omp_get_thread_num());
} // all, including thread 0, will be synchronized here
};
int main(){
# pragma omp parallel
{
# pragma omp single nowait
fct1();
fct2();
}
return 0;
}
I'm trying to change the following C source code to static scheduling, but I don't know how it's done. I've tried to staticbefore #pragma omp parallel private(nthreads, tid):
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
int nthreads, tid;
/* Fork a team of threads giving them their own copies of variables */
static #pragma omp parallel private(nthreads, tid) //I tried it here
{
/* Obtain thread number */
tid = omp_get_thread_num();
printf("Hello World from thread = %d\n", tid);
/* Only master thread does this */
if (tid == 0)
{
nthreads = omp_get_num_threads();
printf("Number of threads = %d\n", nthreads);
}
} /* All threads join master thread and disband */
}
What I expect is that thread 0 gets the first chunk, thread 1 the second chunk, and so on. However, it's randomly now as it's dynamically
I'm trying to synchronize multiple (7) threads. I thought I understood how they work until I was trying it on my code and my threads were still printing out of order. Here is the code:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
void *text(void *arg);
long code[] = {4,6,3,1,5,0,2}; //Order in which to start threads
int num = 0;
pthread_mutex_t lock; //Mutex variable
int main()
{
int i;
pthread_t tid[7];
//Check if mutex worked
if (pthread_mutex_init(&lock, NULL) != 0){
printf("Mutex init failed\n");
return 1;
}
//Initialize random number generator
time_t seconds;
time(&seconds);
srand((unsigned int) seconds);
//Create our threads
for (i=0; i<7; i++)
pthread_create(&tid[i], NULL, text, (void*)code[i]);
//Wait for threads to finish
for (i=0; i<7; i++){
if(pthread_join(tid[i], NULL)){
printf("A thread failed to join\n");
}
}
//Destroy mutex
pthread_mutex_destroy(&lock);
//Exit main
return 0;
}
void *text (void *arg)
{
//pthread_mutex_lock(&lock); //lock
long n = (long) arg;
int rand_sec = rand() % (3 - 1 + 1) + 1; //Random num seconds to sleep
while (num != n) {} //Busy wait used to wait for our turn
num++; //Let next thread go
sleep(rand_sec); //Sleep for random amount of time
pthread_mutex_lock(&lock); //lock
printf("This is thread %d.\n", n);
pthread_mutex_unlock(&lock); //unlock
//Exit thread
pthread_exit(0);
}
So here I am trying to make threads 0-6 print IN ORDER but right now they are still scrambled. The commented out mutex lock is where I originally had it, but then moved it down to the line above the print statement but I'm having similar results. I am not sure where the error in my mutex's are, could someone give a hint or point me in the right direction? I really appreciate it. Thanks in advance!
You cannot make threads to run in order with only a mutex because they go in execution in an unpredictable order.
In my approach I use a condition variable and a shared integer variable to create a queueing system. Each thread takes a number and when the current_n number is equal to the one of the actual thread, it enters the critical section and prints its number.
#include <pthread.h>
#include <stdio.h>
#define N_THREAD 7
int current_n = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t number = PTHREAD_COND_INITIALIZER;
void *text (void *arg) {
int i = (int)arg;
pthread_mutex_lock(&mutex);
while ( i > current_n ) {
pthread_cond_wait(&number, &mutex);
}
//i = current_n at this point
/*I use stderr because is not buffered and the output will be printed immediately.
Alternatively you can use printf and then fflush(stdout).
*/
fprintf(stderr, "I'm thread n=%d\n", i);
current_n ++;
pthread_cond_broadcast(&number);
pthread_mutex_unlock(&mutex);
return (void*)0;
}
int main() {
pthread_t tid[N_THREAD];
int i = 0;
for(i = 0; i < N_THREAD; i++) {
pthread_create(&tid[i], NULL, text, (void *)i);
}
for(i = 0; i < N_THREAD; i++) {
if(pthread_join(tid[i], NULL)) {
fprintf(stderr, "A thread failed to join\n");
}
}
return 0;
}
The output is:
I'm thread n=0
I'm thread n=1
I'm thread n=2
I'm thread n=3
I'm thread n=4
I'm thread n=5
I'm thread n=6
Compile with
gcc -Wall -Wextra -O2 test.c -o test -lpthread
Don't worry about the warnings.
I'm playing with a fairly simple C example. The program creates two threads and starts them in parallel. Each thread is designed to modify a global variable using a Mutex, and print out the value.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
int A=10;
pthread_mutex_t M;
void *codice_Th1(void *arg) {
int i;
for (i=0; i<10;i++){
pthread_mutex_lock(&M);
printf("Thread %s: ", (char *)arg);
A++;
printf("A = %d \n", A);
pthread_mutex_unlock(&M);
sleep(1);
}
pthread_exit(0);
}
void *codice_Th2(void *arg) {
int i;
for (i=0; i<10;i++){
pthread_mutex_lock(&M);
printf("Thread %s: ", (char *)arg);
A--;
printf("A = %d \n", A);
pthread_mutex_unlock(&M);
sleep(1);
}
pthread_exit(0);
}
The main() simply creates the thread, and join the main thread with thread 1 and 2.
int main(){
pthread_t th1, th2;
...
}
What bothers me, is that I get the following output
Thread th1: Thread th2: A = 11
A = 10
Thread th1: A = 11
Thread th2: A = 10
Thread th1: Thread th2: A = 11
A = 10
Thread th1: Thread th2: A = 11
A = 10
Thread th2: Thread th1: A = 9
A = 10
Thread th1: A = 11
Thread th2: A = 10
whereas I would expect every line to execute the printf statements in sequence, given they are inside a mutex.
In other words, I can't understand the ouput
Thread th2: Thread th1: A = 9
I would expect always something similar to
Thread NAME: A = VALUE
Am I missing something?
Never mind, I believe I found the issue. I did not initialize the Mutex with pthread_mutex_init(&M, NULL); before using it.
Setting
int main(){
pthread_t th1, th2;
int ret;
pthread_mutex_init(&M, NULL);
fixed the issue. I assume using pthread_mutex_init is a requirement. Unfortunately, skipping the mutex initialization din't produce any warning or error. The script silently compiled.
Inside the parallel block of my code I reference a thread private variable, tid. tid is assigned in a SECTIONS directive.
However, when I print its value I receive a garbage value inside the parallel block but outside the sections block.
Why do I get a garbage value?
What I know is you usually get a garbage value if you access a variable outside a omp parallel block and not being defined as lastprivate.
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
/* 4 threads, 1 core */
int main (int argc, char *argv[])
{
int nthreads, tid;
/* Fork a team of threads giving them their own copies of variables */
#pragma omp parallel private(tid)
{
#pragma omp sections
{
/* Obtain thread number */
tid = omp_get_thread_num();
printf("Hello World from thread = %d\n", tid);
/* Only master thread does this */
if (tid == 0)
{
nthreads = omp_get_num_threads();
printf("Number of threads = %d\n", nthreads);
}
printf("Inside sections %d \n" ,tid);
}
printf("Out of sections %d \n", tid );
#pragma omp single
{
printf("Inside single block %d \n" , tid);
}
} /* All threads join master thread and disband */
printf("Outside parallel block \n");
}
Below is the output I received:
Hello World from thread = 3
Inside sections 3
Out of sections 0
Inside single block 0
Out of sections 1
Out of sections 3
Out of sections -1078056856
Outside parallel block
Why did tid give that garbage value (-1078056856)?
You should initialize tid before parallel block
To use this its value inside threads declare it as firstprivate(tid) in the pragma omp