I am still learning about threads and I was trying to solve this problem in my code, when I am putting the pthread_join(thread[i],NULL) outside the loop that is creating the threads it always gives me wrong output and Thread with ID = 0 will not work(call the median func) and the last thread will work two times, for better understanding see the output below:
ThreadID= 0, startRow= 0, endRow= 0 // first thread doesn't call the median func
ThreadID= 1, startRow= 1, endRow= 1
ThreadID 1 numOfBright 0 numOfDark 1 numOfNormal 4
ThreadID= 2, startRow= 2, endRow= 2
ThreadID 2 numOfBright 0 numOfDark 1 numOfNormal 4
ThreadID= 3, startRow= 3, endRow= 3
ThreadID 3 numOfBright 0 numOfDark 0 numOfNormal 5
ThreadID= 4, startRow= 4, endRow= 4
ThreadID 4 numOfBright 0 numOfDark 5 numOfNormal 0
ThreadID 4 numOfBright 0 numOfDark 5 numOfNormal 0 // last thread is calling the median func two times.
This is the part of the code that prints the start and end row of each thread.
pthread_t* threads = new pthread_t[num_threads];
struct Th_Range* RANGE = (struct Th_Range*)malloc(sizeof(struct Th_Range*));
int thread_status;
RANGE->SizeOfImage = r; // 2d array with size (n*n) so rows(r) = columns(c)
if (n == num_threads) { //rows = num of threads then every thread will work in a single row
for (int i = 0; i < num_threads; i++) {
RANGE->ThreadId = i;
RANGE->StartRow = RANGE->EndRow = i;
cout << "ThreadID= " << i << ", startRow= " << RANGE->StartRow << ", endRow= " << RANGE->EndRow << endl;
thread_status = pthread_create(&threads[i], NULL, Median, RANGE);
if (thread_status)
exit(-1);
} //for loop ends here
for (int i = 0; i < num_threads; i++)
pthread_join(threads[i],NULL);
} //end of if statement
Here is the part of the code if needed with the median function and the above if statement.
#include <iostream>
#include <bits/stdc++.h>
#include <pthread.h>
pthread_mutex_t Lock;
pthread_mutex_t Pixels;
pthread_mutex_t Pixels2;
using namespace std;
int numOfBright, numOfDark, numOfNormal;
int** Oimage, ** Fimage; //original and filtered image
struct Th_Range {
int SizeOfImage;
int StartRow;
int EndRow;
int ThreadId;
};
void* Median(void* par)
{
struct Th_Range* Num = (struct Th_Range*)par;
int StartRow = Num->StartRow;
int EndRow = Num->EndRow;
int Size = Num->SizeOfImage;
int Neighbour[9] = { 0 };
int dark = 0, bright = 0, normal = 0;
if (EndRow == StartRow)
EndRow += 2;
else
EndRow++;
for (int i = StartRow +1; i < EndRow ; i++)
{
for (int j = 1; j < Size - 1; j++)
{
Neighbour[0] = Oimage[i - 1][j - 1];
Neighbour[1] = Oimage[i - 1][j];
Neighbour[2] = Oimage[i - 1][j + 1];
Neighbour[3] = Oimage[i][j - 1];
Neighbour[4] = Oimage[i][j];
Neighbour[5] = Oimage[i][j + 1];
Neighbour[6] = Oimage[i + 1][j - 1];
Neighbour[7] = Oimage[i + 1][j];
Neighbour[8] = Oimage[i + 1][j + 1];
pthread_mutex_lock(&Pixels); //it can be moved only to lock the Fimage and the numOfBright or any other global variables
sort(Neighbour, Neighbour + 9);
Fimage[i][j] = Neighbour[4];
if (Neighbour[4] > 200) {
bright++;
numOfBright++;
}
else if (Neighbour[4] < 50) {
dark++;
numOfDark++;
}
else {
normal++;
numOfNormal++;
}
pthread_mutex_unlock(&Pixels);
}
}
pthread_mutex_lock(&Pixels2); //when I try to remove this lock the output gets interrupted
cout << "ThreadID " << Num->ThreadId << " numOfBright " << bright << " numOfDark " << dark << " numOfNormal " << normal<<endl;
pthread_mutex_unlock(&Pixels2);
pthread_exit(NULL);
}
int main(int argc, char* argv[])
{
int num_threads, n, r, c; // n is the size of the matrix r and c are rows and columns
numOfNormal = numOfDark = numOfBright = 0;
if (argc >= 2)
num_threads = atoi(argv[1]);
else
exit(-1);
ifstream cin("input.txt");
cin >> n;
r = c = n + 2;
Oimage = new int* [r]();
Fimage = new int* [r]();
for (int i = 0; i < c; i++)
{
Oimage[i] = new int[c]();
Fimage[i] = new int[c]();
}
for (int i = 1; i < r - 1; i++)
for (int j = 1; j < c - 1; j++)
cin >> Oimage[i][j];
pthread_t* threads = new pthread_t[num_threads];
struct Th_Range* RANGE = (struct Th_Range*)malloc(sizeof(struct Th_Range*));
RANGE->SizeOfImage = r;
if (n == num_threads) { //rows = num of threads then every thread will work in a single row
//n+2
int thread_status;
for (int i = 0; i < num_threads; i++) {
RANGE->ThreadId = i;
RANGE->StartRow = RANGE->EndRow = i;
// pthread_mutex_lock(&Lock);
cout << "ThreadID= " << i << ", startRow= " << RANGE->StartRow << ", endRow= " << RANGE->EndRow << endl;
thread_status = pthread_create(&threads[i], NULL, Median, RANGE);
if (thread_status)
exit(-1);
}
}
I tried to move pthread_join inside the loop of pthread_create it gives a correct output but of course it is a wrong solution. I have no idea what to do next. Thanks in advance