Hi all,
I have create this program to manage multiple threads multiple queues, for elaborate a series of images. Every thread pop an image from a queue, works on it, and push it in output queue.
Thanks to different advices received here from other users, I have create this code, but the threads behaviour it's strange: threads 1, 2, 3 don't elaborate all images that push thread 0.
I have check and re-check code, but I don't know where the problem is. Can someone help me? Help me to find where is the problem?
This is the code (UPDATED):
#include <opencv\cv.h>
#include <opencv\highgui.h>
#include <stdio.h>
#include <windows.h>
#include <process.h>
#include <queue>
using namespace std;
using namespace cv;
template<typename T>
class coda_concorr
{
private:
std::queue<T> la_coda;
HANDLE mutex;
public:
bool complete;
coda_concorr()
{
mutex = CreateMutex(NULL,FALSE,NULL);
complete = false;
}
~coda_concorr()
{
ReleaseMutex(mutex);
}
void push(T& data)
{
WaitForSingleObject(mutex,INFINITE);
la_coda.push(data);
ReleaseMutex(mutex);
}
bool vuota() const
{
WaitForSingleObject(mutex,INFINITE);
bool RetCode = la_coda.empty();
ReleaseMutex(mutex);
return RetCode;
}
bool try_pop(T& popped)
{
WaitForSingleObject(mutex,INFINITE);
while (la_coda.empty()){
ReleaseMutex(mutex);
return false;
}
popped = la_coda.front();
la_coda.pop();
ReleaseMutex(mutex);
return true;
}
};
struct Args
{
coda_concorr<cv::Mat> in;
coda_concorr<cv::Mat> *out; };
void puts (void* param){
Args* arg = (Args*)param;
int i=0;
Mat image;
while(arg->in.vuota()){
Sleep(0.01);
cout<<endl<<"Thread 0 in attesa di dati..elaborazioni fatte "<<i<<endl;
}
while(arg->in.try_pop(image)){
arg->out->push(image);
i++;
}
arg->out->complete=true;
cout<<endl<<"Thread 0 terminato con "<<i<<" elaborazioni."<<endl;
_endthread();
}
void grey (void *param){
Mat temp1,temp2;
int add = 0;
Args* arg = (Args*)param;
while(arg->in.vuota()){
Sleep(0.01);
cout<<endl<<"Thread 1 in attesa di dati..elaborazioni fatte "<<add<<endl;
}
while(arg->in.try_pop(temp1)){
threshold(temp1,temp2,128,255,THRESH_BINARY);
arg->out->push(temp2);
add++;
}
arg->out->complete=true;
cout<<endl<<"Thread 1 terminato con "<<add<<" elaborazioni."<<endl;
_endthread();
}
void soglia(void *param){
Mat temp1a,temp2a;
int add=0;
Args* arg = (Args*)param;
while(arg->in.vuota()){
Sleep(0.01);
cout<<endl<<"Thread 2 in attesa..elaborazioni fatte "<<add<<endl;
}
while(arg->in.try_pop(temp1a)){
threshold(temp1a,temp2a,128,255,THRESH_BINARY);
arg->out->push(temp2a);
add++;
}
arg->out->complete=true;
cout<<endl<<"Thread 2 terminato con "<<add<<" elaborazioni."<<endl;
_endthread();
}
void finitura(void *param){
Mat temp1b,temp2b,temp2c;
int add = 0;
Args* arg = (Args*)param;
while(arg->in.vuota()){
Sleep(0.01);
cout<<endl<<"Thread 3 in attesa..elaborazioni fatte "<<add<<endl;
}
while(arg->in.try_pop(temp1b)){
erode(temp1b,temp2b,cv::Mat());
dilate(temp2b,temp2c,Mat());
arg->out->push(temp2c);
add++;
}
arg->out->complete=true;
cout<<endl<<"Thread 3 terminato con "<<add<<" elaborazioni."<<endl;
_endthread();
}
void contorno (void *param){
Mat tempA,tempB;
Args* arg = (Args*)param;
}
int main()
{
coda_concorr<cv::Mat> ingresso;
coda_concorr<cv::Mat> uscita;
Mat out;
LARGE_INTEGER count1, count2, freq;
double elapsed;
Args init,dati,dati2,dati3;
cout<<endl<<"Elaborazione di immagini con 3 threads concorrenti e code dinamiche."<<endl;
cout<<endl<<"Avvio elaborazione.."<<endl;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter (&count1);
Mat temp[10];
for(int i=0;i<10;i++){
temp[i] = imread("C:/OPENCV/Test/imgtest/bird1.jpg",1);
ingresso.push(temp[i]);
}
init.in=ingresso;
init.out=&dati.in;
dati.out=&dati2.in;
dati2.out=&dati3.in;
dati3.out=&uscita;
HANDLE handle0,handle1,handle2,handle3;
handle0 = (HANDLE) _beginthread(puts,0,&init);
handle1 = (HANDLE) _beginthread(grey,0,&dati);
handle2 = (HANDLE) _beginthread(soglia,0,&dati2);
handle3 = (HANDLE) _beginthread(finitura,0,&dati3);
cout<<endl<<"..Join dei threads..."<<endl;
WaitForSingleObject(handle0,INFINITE);
WaitForSingleObject(handle1,INFINITE);
WaitForSingleObject(handle2,INFINITE);
WaitForSingleObject(handle3,INFINITE);
QueryPerformanceCounter (&count2);
elapsed = (count2.QuadPart - count1.QuadPart) * 1000.0 / freq.QuadPart;
cout <<endl<<"Tempo di esecuzione approssimativo: " <<elapsed<<" ms."<<endl;
system("PAUSE");
return 0;
}
How force threads next to zero, that always have to "check queue even it's empty, and works for all pushed images"? I'm desperate...the problem is in queue, in thread function or somewhere? Because every launch of program, different result...why?
Thanks in advance for your attention...please help me!!