I'm trying to understand pthread conditions.
For doing so, I wrote a very basic program but, no matter how many manuals and explanations I read, I just cannot understand how things work.
#include <iostream>
#include <pthread.h>
using namespace std;
#define NT 3
#define ITERATIONS 5
int countDone=0;
int a[NT] = {10, 20, 30};
pthread_cond_t doneCond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t doneMutex = PTHREAD_MUTEX_INITIALIZER;
void * thread_start(void* num){
int currIt=0;
while(currIt < ITERATIONS){
cout << pthread_self() << "my number is " << a[(int)num] << endl;
a[(int)num]++;
pthread_mutex_lock(&doneMutex);
countDone++;
if(countDone == NT)
pthread_cond_signal(&doneCond);
while(countDone != 0)
pthread_cond_wait(&doneCond, &doneMutex);
pthread_mutex_unlock(&doneMutex);
currIt++;
}
pthread_exit(NULL);
}
int main(){
pthread_t tidVec[NT];
int i, currIt=0, ret;
//creating threads
for(i=0; i<NT; i++)
pthread_create(&tidVec[i], NULL, &thread_start, (void*)i);
while(currIt < ITERATIONS){
cout << "---Iteration " << currIt << endl;
pthread_mutex_lock(&doneMutex);
while(countDone < NT)
pthread_cond_wait(&doneCond, &doneMutex);
countDone = 0;
pthread_cond_broadcast(&doneCond);
pthread_mutex_unlock(&doneMutex);
currIt++;
}
//waiting for threads termination
for(i=0; i<NT; i++)
pthread_join(tidVec[i], (void**)&ret);
pthread_cond_destroy(&doneCond);
pthread_mutex_destroy(&doneMutex);
return 0;
}
What I want it to do is: at each iteration, every thread prints the number assigned to itself in the array a, increments the value and then increments the counter countDone (which counts how many threads have already done their job).
The last thread that finishes its job "tells" the main the they all are done.
The main sets the counter to zero, so that a new iteration can begin.
And so on for 5 iterations.
What I get as an output is:
---Iteration 0
3057584960my number is 30
3065977664my number is 20
3074370368my number is 10
---Iteration 1
3057584960my number is 31
and then it gets stuck.
Can you please help me figure out what is going on here?
Thank you.
Related
I am observing strange behavior using pthreads. Note the following code -
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <pthread.h>
#include <unistd.h>
typedef struct _FOO_{
int ii=0;
std::string x="DEFAULT";
}foo;
void *dump(void *x)
{
foo *X;
X = (foo *)x;
std::cout << X->x << std::endl;
X->ii+=1;
}
int main(int argc, char **argv)
{
foo X[2];
const char *U[2] = {"Hello", "World"};
pthread_t t_id[2];
int t_status[2];
/*initalize data structures*/
for(int ii=0; ii < 2; ii+=1){
X[ii].x=U[ii];
}
foo *p = X;
for(int ii=0; ii < 2; ii+=1){
t_status[ii] = pthread_create(&t_id[ii], NULL, dump, (void *)p);
std::cout << "Thread ID = " << t_id[ii] << " Status = " << t_status[ii] << std::endl;
p+=1;
}
//sleep(1); /*if this is left commented out, one of the threads do not execute*/
for(int ii=0; ii < 2; ii+=1){
std::cout << pthread_join(t_status[ii], NULL) << std::endl;
}
for(int ii=0; ii < 2; ii+=1){
std::cout << X[ii].ii << std::endl;
}
}
When I leave the sleep(1) (between thread create and join) call commented out, I get erratic behavior in the randomly only 1 of the 2 thread run.
rajatkmitra#butterfly:~/mpi/tmp$ ./foo
Thread ID = 139646898239232 Status = 0
Hello
Thread ID = 139646889846528 Status = 0
3
3
1
0
When I uncomment sleep(1). Both threads execute reliably.
rajatkmitra#butterfly:~/mpi/tmp$ ./foo
Thread ID = 140072074356480 Status = 0
Hello
Thread ID = 140072065963776 Status = 0
World
3
3
1
1
The pthread_join() should hold up exit from the program, till both threads complete, but in this example I am unable to get that to happen without the sleep() function. I really do not like the implementation with sleep(). Can someone tell me if I am missing something??
See Peter's note -
pthread_join should be called with the thread id, not the status value that pthread_create returned. So: pthread_join(t_id[ii], NULL), not pthread_join(t_status[ii], NULL). Even better, since the question is tagged C++, use std::thread. –
Pete Becker
I'm working on a college assignment and have been tasked with showing a basic mutex lock example. I've never worked with threads in any form, so I'm a total beginner working with POSIX threads in C++.
What I'm trying to get the program to do is create 1000 threads that increment a global integer by 1000.
#include <iostream>
#include <stdlib.h>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>
#include <thread>
pthread_t threadArr[1000];
pthread_mutex_t lock;
// Global int to increment
int numberToInc = 0;
void* incByTwo(void*)
{
pthread_mutex_lock(&lock);
for(int j = 0; j < 1000; j++){
numberToInc += 1;
}
pthread_mutex_unlock(&lock);
return NULL;
}
int main()
{
//Creates 1000 threads with incByTwo func
for(int i = 0; i < 1000; i++){
pthread_create(&threadArr[i], NULL, incByTwo, NULL);
}
std::cout << "\n" << numberToInc << "\n";
return 0;
}
The following produces a series of different results, obviously because the threads are executing concurrently, right?
Now, I've gotten it to work correctly by inserting
for(int i = 0; i < 1000; i++){
pthread_join(threadArr[i], NULL);
}
After the thread creation loop, but then removing the mutex locks, it still works. I've been trying to piece out how pthread_join works but I'm a little lost. Any advice?
Sorted a way to show the mutex lock in action. So when I output the global var in the function, without mutex locks it has the potential to show the results out of order.
Running the number range with mutex locks, out looks like:
1000
2000
3000
... (etc)
10000
With mutex locks removed, the output can vary in the order.
E.g.
1000
2000
4000
6000
3000
5000
7000
8000
9000
10000
While the final result of the three threads is correct, the sequence is out of order. In the context of this program it doesn't really matter but I'd imagine if it's passing inconsistently sequenced values it messes things up?
pthread_t threadArr[10];
pthread_mutex_t lock;
int numberToInc = 0;
void* incByTwo(void*)
{
pthread_mutex_lock(&lock);
for(int j = 0; j < 1000; j++){
numberToInc += 1;
}
std::cout << numberToInc << "\n";
pthread_mutex_unlock(&lock);
return NULL;
}
int main()
{
if (pthread_mutex_init(&lock, NULL) != 0)
{
printf("\n mutex init failed\n");
return 1;
}
for(int i = 0; i < 10; i++){
pthread_create(&threadArr[i], NULL, incByTwo, NULL);
}
pthread_join(threadArr[0], NULL);
return 0;
}
I'm currently working on a program that takes an array of 10000 random numbers, splits it evenly with five threads, and those five threads split further into 20 threads each evenly. The purpose is to find the ultimate minimum number from that original 10000 random number array.
I believe I'm on the right track. Upon further examination, something is wrong with my array traversal on level 1. I can only see one of the first 5 thread's 20 threads return. The information that comes back appears correct, but when I try to cout the information as it is happening, I get blank space for the return minimums of 4 of the L1 thread's L2 threads. (Sorry if that's a bit confusing.)
Would anyone be able to give me any tips on what to look out for? I will provide the code below.
Bear in mind, efficiency is not the goal of this program. Demonstrating multithreading is.
#include <sys/time.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctime>
#include <iostream>
#include <pthread.h>
#include <cstdlib>
#include <unistd.h>
/*
Macros were used to make modulation easier and to ease reading of the code
*/
#define L1_THREADS 5 //# of level 1 threads
#define L2_THREADS 20 //# of level 2 threads
//#define L1_ARRAY 5 //eventually unused
#define L2_ARRAY 2000 //size of level 2 array
using namespace std;
//structure to house the Thread Parameters required
struct ThreadParameters{
int* array;
int start;
int end;
int smallest;
};
//function to find the minimum value at the bottom level of the thread spread
void* find_min(void* args){
struct ThreadParameters* specs = (struct ThreadParameters*)args;
int *array = specs->array;
int start = specs->start;
int end = specs->end;
int smallest = array[start];
for(int i = start; i < end; i++){
if(array[i] < smallest){
smallest = array[i];
}
}
specs->smallest = smallest;
return NULL;
}
//function to find the minimum value of the values returned by the threads it creates
void* find_first(void* args){
pthread_t threads2[L2_THREADS] = {0};
struct ThreadParameters thread2_parameters[L2_THREADS] = {0};
struct ThreadParameters* specs = (struct ThreadParameters*)args;
int *array = specs->array;
int start = specs->start;
int end = specs ->end;
int smallest = array[start];
//Level 1, creates the 20 threads for level 2
for(int i = 0; i < L2_THREADS; i++){
thread2_parameters[i].array = array;
thread2_parameters[i].start = i*(L2_ARRAY/L2_THREADS);
thread2_parameters[i].end = (i+1)*(L2_ARRAY/L2_THREADS);
pthread_create(&threads2[i], NULL, find_min, &thread2_parameters[i]);
}
for(int i = 0; i < L2_THREADS; i++){
pthread_join(threads2[i], NULL);
}
cout << "Minimums from L2 threads: ";
for(int i = start; i < L2_THREADS; i++){
cout << "[" << thread2_parameters[i].smallest << "]";
if(thread2_parameters[i].smallest < smallest){
smallest = thread2_parameters[i].smallest;
}
}
cout << endl;
specs->smallest = smallest;
return NULL;
}
int main(){
time_t t;
int n = 10000;
int randnum[n]; /* array of random numbers */
/* Initialize random number generator */
srand((unsigned) time(&t));
/* Generate random numbers */
for (int i = 0; i < n; i++) {
randnum[i] = rand()%10000 +1;
}
/* end of random number generation code */
pthread_t threads1[L1_THREADS] = {0};
struct ThreadParameters thread1_parameters[L1_THREADS] = {0};
//int min[L1_ARRAY];
int smallest;
smallest = randnum[0];
//Level 0, creates the first five threads for level 1
for(int i = 0; i < L1_THREADS; i++){
thread1_parameters[i].array = randnum;
thread1_parameters[i].start = i*(n/L1_THREADS);
thread1_parameters[i].end = (i+1)*(n/L1_THREADS);
pthread_create(&threads1[i], NULL, find_first, &thread1_parameters[i]);
}
for(int i = 0; i < L1_THREADS; i++){
pthread_join(threads1[i], NULL);
}
cout << "Minimums from L1 threads: ";
//finds the ultimate minimum after L1 threads return with their values
for(int i = 0; i < L1_THREADS; i++){
cout << "[" << thread1_parameters[i].smallest << "]";
if(thread1_parameters[i].smallest < smallest){
smallest = thread1_parameters[i].smallest;
}
}
cout << "\nThe ultimate minimum is " << smallest << endl;
return 0;
}
My programming is going in dead lock.I am trying to print three numbers 3 4 5 sequentially for 50 times using three threads using semaphore synchronization.
Please help me.
Below is the code
#include <iostream>
#include <pthread.h>
#include <semaphore.h>
using namespace std;
sem_t sem1;
sem_t sem2;
sem_t sem3;
void * fun1(void *)
{
for(int i = 0; i < 50 ; i++)
{
sem_wait(&sem1);
sem_wait(&sem3);
cout<<"3"
sem_post(&sem2);
sem_post(&sem3);
}
}
void * fun2(void *)
{
for(int i = 0; i < 50 ; i++)
{
sem_wait(&sem2);
sem_wait(&sem3);
cout<<"4";
sem_post(&sem3);
sem_post(&sem1);
}
}
void * fun3 (void *)
{
for(int i = 0; i< 50; i++)
{
sem_wait(&sem2);
sem_wait(&sem3);
cout<<"5";
sem_post(&sem1);
sem_post(&sem2);
}
}
int main()
{
pthread_t t1;
pthread_t t2;
pthread_t t3;
sem_init(&sem1,0,1);
sem_init(&sem2,0,0);
sem_init(&sem3,0,1);
pthread_create(&t1,NULL,&fun1,NULL);
pthread_create(&t2,NULL,&fun2,NULL);
pthread_create(&t3,NULL,&fun3,NULL);
pthread_join(t1,NULL);
pthread_join(t2,NULL);
pthread_join(t3,NULL);
return 1;
}
Please help me to understand and solve this deadlock.Provide suggestions also i can do this for example 3 4 5 6 using 4 etc threads
Please help me to understand and solve this deadlock.
There is indeed a deadlock in your code. Consider at the beginning, thread 1 first gets 2 semaphores and call cout << "3". After posting sem2 and sem3, it is possible that thread 3 immediately gets these 2 sem, then call cout << "5". However, after thread 3 posting sem1 and sem2, no one can reach a cout << statement, because sem3's value is 0 and everyone needs to pass a wait of sem3.
If you are wondering why there is totally no output, it's because the buffer inside iostream. For console output, "\n" will flush buffer, so if you replace "3" by "3\n", you can see the output.
Provide suggestions also i can do this for example 3 4 5 6 using 4 etc threads
In the following code, you should see the symmetry, which can be easily generalized to any number of thread. And you should always call sem_destroy after using semaphore, otherwise you might get system level resource leak.
#include <iostream>
#include <pthread.h>
#include <semaphore.h>
using namespace std;
sem_t sem1;
sem_t sem2;
sem_t sem3;
void * fun1(void *)
{
for(int i = 0; i < 50 ; i++)
{
sem_wait(&sem1);
cout<<"3\n";
sem_post(&sem2);
}
}
void * fun2(void *)
{
for(int i = 0; i < 50 ; i++)
{
sem_wait(&sem2);
cout<<"4\n";
sem_post(&sem3);
}
}
void * fun3 (void *)
{
for(int i = 0; i< 50; i++)
{
sem_wait(&sem3);
cout<<"5\n";
sem_post(&sem1);
}
}
int main()
{
pthread_t t1;
pthread_t t2;
pthread_t t3;
sem_init(&sem1,0,1);
sem_init(&sem2,0,0);
sem_init(&sem3,0,0);
pthread_create(&t1,NULL,&fun1,NULL);
pthread_create(&t2,NULL,&fun2,NULL);
pthread_create(&t3,NULL,&fun3,NULL);
pthread_join(t1,NULL);
pthread_join(t2,NULL);
pthread_join(t3,NULL);
sem_destroy(&sem1);
sem_destroy(&sem2);
sem_destroy(&sem3);
return 1;
}
I use clock() in library to calculate excution time of a function, which is BubbleSort(..) function in my code below. But probleam is that the return execution time always = 0 (and it shows no unit, too).
This is my code:
#include <iostream>
#include <ctime>
using namespace std;
void BubbleSort(int arr[], int n)
{
for (int i = 1; i<n; i++)
for (int j = n-1; j >=i; j-- )
if (arr[j] < arr[j-1])
{
int temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
}
return;
}
int main()
{
int arr[] = {4,1,7,2,6, 17, 3, 2, 8,1};
int len = sizeof(arr)/sizeof(int);
cout << "Before Bubble Sort: \n";
for (int i=0;i<len;i++)
{
cout << arr[i] << " ";
}
clock_t start_s=clock(); // begin
BubbleSort(arr,len);
clock_t stop_s=clock(); // end
cout << "\nAfter Bubble Sort: \n";
for (int i=0;i<len;i++)
{
cout << arr[i] << " ";
}
// calculate then print out execution time - currently always returns 0 and I don't know why
cout << "\nExecution time: "<< (double)(stop_s - start_s)/CLOCKS_PER_SEC << endl;
//system("pause");
return 0;
}
I haven't known how to fix this problem yet .. So hope you guys can help me with this. Any comments would be very appreciated. Thanks so much in advanced !
As you have only a very small array, the execution time is probably much shorter than the resolution of clock(), so you either have to call the sort algorithm repeatedly or use another time source.
I modified your code as such and both start end stop have the value of 0. (ubuntu 13.10)
std::cout<<"start: "<<start_s<<std::endl;
BubbleSort(arr,len);
clock_t stop_s=clock(); // end
std::cout<<"stop: "<<stop_s<<std::endl;
you probably want something more like gettimeofday()
this http://www.daniweb.com/software-development/cpp/threads/120862/clock-always-returns-0 is an interesting discussion of the same thing. the poster concluded that clock()(on his machine) had a resolution of about 1/100 of a sec. and your code is probably ( almost certainly) running faster than that