这些线程的奇怪行为......为什么会发生这种情况? [英] A Strange behaviour of these threads...why happened this?

查看:103
本文介绍了这些线程的奇怪行为......为什么会发生这种情况?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,

我创建了这个程序来管理多个线程的多个队列,用于精心制作一系列图像。每个线程从队列中弹出一个图像,对其进行处理,然后将其推送到输出队列中。



感谢其他用户收到的不同建议,我创建了这个代码,但线程行为很奇怪:线程1,2,3没有详细说明推送线程0的所有图像。



我检查并重新检查代码,但我不知道问题出在哪里。有人能帮我吗?帮我找出问题出在哪里?



这是代码(更新):



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;

/*inizio della parte relativa alla coda thread safe*/

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;
    }
};

//pacchetto per passaggio ai thread
struct Args
{
	coda_concorr<cv::Mat> in;
	coda_concorr<cv::Mat> *out; //puntatore a coda successiva
};

//funzione di popolamento coda
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++;
	}
	//flag completato
	arg->out->complete=true;
	cout<<endl<<"Thread 0 terminato con "<<i<<" elaborazioni."<<endl;
	_endthread();
}

//funzione grey
void grey (void *param){
	Mat temp1,temp2;
	int add = 0;
	Args* arg = (Args*)param;
	//se la trova vuota
	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++;
		}
		
	//flag completato
	arg->out->complete=true;
	cout<<endl<<"Thread 1 terminato con "<<add<<" elaborazioni."<<endl;
	_endthread();
}

//funzione sogliatura
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++;
		}
		//flag completato
	 arg->out->complete=true;
	 cout<<endl<<"Thread 2 terminato con "<<add<<" elaborazioni."<<endl;
	 _endthread();
	
}

//funzione erosione/dilate
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++;
		}
		//flag completato
	 arg->out->complete=true;
	 cout<<endl<<"Thread 3 terminato con "<<add<<" elaborazioni."<<endl;
	_endthread();
}

//funzione tracciamento contorno immagini
void contorno (void *param){
	Mat tempA,tempB;
	Args* arg = (Args*)param;
}

//main
int main()
{
	//dichiarazione delle due code principali
	coda_concorr<cv::Mat> ingresso;
	coda_concorr<cv::Mat> uscita;

	//array locali di ingresso e uscita
	Mat out;
	
	//dichiarazione variabili per contatore
	LARGE_INTEGER count1, count2, freq;
	double elapsed;

	//dichiarazione code
	Args init,dati,dati2,dati3;
	

	cout<<endl<<"Elaborazione di immagini con 3 threads concorrenti e code dinamiche."<<endl;
	cout<<endl<<"Avvio elaborazione.."<<endl;

	//avvio contatori
	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]);
	}
	//puntatori per il passaggio alla coda successiva
	init.in=ingresso;
	init.out=&dati.in;
	dati.out=&dati2.in;
	dati2.out=&dati3.in;
	dati3.out=&uscita;

	//dichiarazione delle handle
	HANDLE handle0,handle1,handle2,handle3;

	//dichiarazione dei threads
	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;
	//join
	WaitForSingleObject(handle0,INFINITE);
	WaitForSingleObject(handle1,INFINITE);
	WaitForSingleObject(handle2,INFINITE);
	WaitForSingleObject(handle3,INFINITE);
	
	//chiusura contatori
	QueryPerformanceCounter (&count2);
	
//output di verifica disabilitato ora
	/*while(dati3.out->try_pop(out)){
		imshow("immagine",out);
		waitKey(50);
	}*/

	//calcolo tempo trascorso
	elapsed = (count2.QuadPart - count1.QuadPart) * 1000.0 / freq.QuadPart;
	//visualizzo
	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!!

推荐答案

引用:

for(int i = 0; i< 10; i ++){

Mat temp [10];

temp [i] = imread(C:/OPENCV/Test/imgtest/bird1.jpg,1);

ingresso.push(temp [i]);

}

for(int i=0;i<10;i++){
Mat temp[10];
temp[i] = imread("C:/OPENCV/Test/imgtest/bird1.jpg",1);
ingresso.push(temp[i]);
}



我猜这与'奇怪的行为'无关,但是上面的行中有错误,即你是在每次迭代时重新创建 temp 数组,更糟糕的是,它是临时您通过引用传递 推送功能。


I guess is not related with the 'strange behaviour', however there are mistakes in the above lines, namely you are re-creating the temp array at each iteration, and, worse, it is a temporary you're passing by reference to the push function.


这篇关于这些线程的奇怪行为......为什么会发生这种情况?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆