Thread synchronisation



  • Hi Leute,

    ich hab ein Problem, und zwar arbeite ich mit mehreren Threads.
    Sprich ein Thread schreibt in eine queue ein strukt ein anderer liest aus dem heap zwei einträge aus. Dieser teilt die einträge unter vier anderen Threads auf.
    Die vergleichen die einträge.
    Es sollte eine Art MotionDetect werden. Die Einträge sind Zeiger auf die
    drei DIB Sektoren (Info, Header und die Pixel an sich).

    Der heap ist mit CRITICAL_SECTION threadsicher, aber wegen der Koordination hab ich ein Problem.
    Gibt es eine Funktion die einen thread "schlafen" legt bis er wieder aufgerufen wird? Nach dem Motto wait & notify? Sonst muss ich immer ein Schleife laufen lassen um den Status abzufragen und das kostet rechenleistung...

    Danke euch schon mal1!!!!





  • ich habe die frage nicht 100% verstanden.
    aber ich hatte schon einähnliches problem, welches ich mit

    Synchronize()
    

    glöst habe



  • Wow! 😮

    Ging aber schnell!
    @miller_m:
    Ich schau mir gleich mal den link an. Denke das es genau sowas ist!
    @BigNEal:
    selbiges

    Danke!!!!



  • Jawohl genau!!

    WaitForSingleObject ist genau richtig! Danke!!!!!!!!!
    EDIT:
    Doch nicht... Kann mir jemand sagen, warum das nicht geht?!?!?

    //*****************************************************************************
    //	Initialisation der statischen Variablen
    //*****************************************************************************
    
    CRITICAL_SECTION cs;
    HANDLE hStartReading;
    HANDLE hThreadCommunication;
    HANDLE hInitializeAll;
    
    static int THREAD_STATUS[MAX_THREAD];
    static thread_data thread_exercise[MAX_THREAD];
    
    static HWND hWindow;
    static CHeap * pCHeap;
    static int count = 0;
    
    //*****************************************************************************
    //	Funktion die in den Heap schreibt
    //*****************************************************************************
    bool addDIB(FILE * bmp)
    {
    	EnterCriticalSection(&cs);
    
    	DIB_file * temp = new DIB_file;
    
    	//größe der Datei ermittlen
    	fseek(bmp,0,SEEK_END);
    	long size = ftell(bmp);
    	fseek(bmp,0,SEEK_SET);
    
    	temp->file = new BITMAPFILEHEADER;
    	temp->info = new BITMAPINFOHEADER;
    
    	fread(temp->file,sizeof(BITMAPFILEHEADER),1,bmp);
    	fread(temp->info,sizeof(BITMAPINFOHEADER),1,bmp);
    
    	pCHeap->pushElement(temp);
    
    	LeaveCriticalSection(&cs);
    
    	return true;
    }
    
    //*****************************************************************************
    //	Funktion die aus dem heap liest
    //*****************************************************************************
    bool getDIB(DIB_file * temp)
    {
    	bool succes;
    	EnterCriticalSection(&cs);
    	succes = pCHeap->getElement(temp);
    	LeaveCriticalSection(&cs);
    	if (succes)
    		return true;
    	else
    		return false;
    }
    
    //*****************************************************************************
    //	Thread der einen Bildteil der ihm zugewiesen wird vergleicht
    //*****************************************************************************
    void Thread(PVOID pVoid)
    {
    	int number = (int) pVoid;
    	count += 1;
    	THREAD_STATUS[number]= THREAD_WAITING;
    
    	SendMessage(hWindow,WM_PAINTMESSAGE,0,(LPARAM)"Start");
    
    	if (count == MAX_THREAD)
    		SetEvent(hInitializeAll);
    
    	//Warte bis Parent daten gelesen und in array geschrieben hat
    	WaitForSingleObject(hThreadCommunication, INFINITE);
    
    	long heigth = thread_exercise[number].info->biHeight;
    
    	if (number == MAX_THREAD-1)
    		ResetEvent(hThreadCommunication);
    		SetEvent(hThreadCommunication);
    
    	SendMessage(hWindow,WM_PAINTMESSAGE,0,(LPARAM)"Ending");
    	_endthread();
    }
    
    //*****************************************************************************
    //	Prototyp. Erzeugt filehandels und gibt sie an addDIB weiter
    //*****************************************************************************
    void write(PVOID pVoid)
    {
    	int sendEvent = 2;
    
    	//Warte bis alle Threads erstellt sind
    	WaitForSingleObject(hInitializeAll, INFINITE);
    
    	SendMessage(hWindow,WM_PAINTMESSAGE,0,(LPARAM)"BeginRead");
    
    	SetEvent(hStartReading);
    	_endthread();
    }
    
    //*****************************************************************************
    //	liefert den Status der Threads zum Bildervergleich zurück
    //*****************************************************************************
    int getStatus()
    {
    	//wenn ein Thread einen Error erzeugt ist die ganze Operation Error
    	for (int i = 0; i < MAX_THREAD ; i++)
    		if (THREAD_STATUS[i] == THREAD_ERROR)
    			return THREAD_ERROR;
    
    	//solange nicht alle Thread beendet sind, wird noch auf arbeit gesetzt
    	for (int i = 0; i < MAX_THREAD ; i++)
    		if (THREAD_STATUS[i] == THREAD_WORKING)
    			return THREAD_WORKING;
    
    	return THREAD_WAITING;
    }
    
    //*****************************************************************************
    //	setzt eine Status aller Threads
    //*****************************************************************************
    bool setStatus(int status)
    {
    	for(int i = 0; i < MAX_THREAD; i++)
    	{
    		THREAD_STATUS[i] = status;
    	}
    	return true;
    }
    
    //*****************************************************************************
    //	liest informationen aus dem Heap und gibt sie an die Threads zur 
    //	verarbeitung weiter
    //*****************************************************************************
    void read(PVOID pVoid)
    {
    	//Starts threads with threadnumber
    	setStatus(THREAD_ERROR);
    	for(int i=0; i<MAX_THREAD;i++)
    	{
    		_beginthread(Thread,0,(void *)i);
    	}
    
    	WaitForSingleObject(hInitializeAll, INFINITE);
    	SendMessage(hWindow,WM_PAINTMESSAGE,0,(LPARAM)"WriteWait");
    
    	WaitForSingleObject(hStartReading, INFINITE);
    	SendMessage(hWindow,WM_PAINTMESSAGE,0,(LPARAM)"WriteGet");
    
    	//Starte verarbeitung
    	int status = 0;
    	DIB_file * temp1 = new DIB_file;
    	DIB_file * temp2 = new DIB_file;
    
    	while(getStatus() != THREAD_ERROR)
    	{
    		if (getDIB(temp1) && getDIB(temp2))
    		{
    			for (int i = 0; i < MAX_THREAD; i++)
    			{
    				thread_exercise[i].file = temp1->file;
    				thread_exercise[i].info = temp1->info;
    			}
    		}
    		SetEvent(hThreadCommunication);
    		WaitForSingleObject(hThreadCommunication, INFINITE);
    		break;
    	}
    
    	SendMessage(hWindow,WM_PAINTMESSAGE , 0, (LPARAM)"WriteEnd.");
    	_endthread();
    }
    
    //*****************************************************************************
    //	Initialisiert die Hauptthreads und beendet sich dann
    //*****************************************************************************
    bool startIOThread(HWND hWnd)
    {
    	hWindow = hWnd;
    	pCHeap = new CHeap(20);
    
    	hStartReading = CreateEvent(NULL,FALSE,FALSE,"FirstListener");
    	hThreadCommunication = CreateEvent(NULL, FALSE, FALSE, "SecondListener");
    	hInitializeAll = CreateEvent(NULL, FALSE, FALSE, "ThirdListener");
    
    	for(int i = 0; i < MAX_THREAD; i++)
    	{
    		thread_exercise[i].file = new BITMAPFILEHEADER;
    		thread_exercise[i].info = new BITMAPINFOHEADER;
    	}
    
    	InitializeCriticalSection(&cs);
    
    	_beginthread(write,0,NULL);
    	_beginthread(read,0, NULL);
    
    	return true;
    }
    

    Zuerst wird startIOThread aufgerufen. Wenn write-thread gestartet hat, initialisiert er die Thraed-threads und dann wird gewartet bis alle initialisiert sind.
    write-Thread beginnt und hStartRead wird gesetzt... Da passiert dann nix!!!!
    Und ich weiß nicht warum!!!!!

    Danke wenn jemand was weiß!!!!



  • Hab grad keine Lust mir den kompletten Code anzusehen, aber zu WaitforSingleObject schau mal hier:

    http://www.c-plusplus.net/forum/viewtopic.php?t=89356&highlight=createevent

    Ach ja, gab es da nicht
    Look Thread1
    Thread 2 .. wird ausgeführt
    Unlook Thread 1
    oder so etwas



  • niemayd schrieb:

    write-Thread beginnt und hStartRead wird gesetzt... Da passiert dann nix!!!!
    Und ich weiß nicht warum!!!!!

    Zunächst solltest du für die gegenseitige Aktivierung von Thread und read nicht dasselbe Event benutzen.

    Außerdem sind deine Abfragen der Art

    if (number == MAX_THREAD-1)
    

    reichlich gewagt. Du kannst dich nicht darauf verlassen, dass die Threads in der Reihenfolge abgearbeitet werden, in der sie erzeugt wurden.

    Warum sind Thread und read überhaupt getrennte Threads? Wenn sie sowieso immer nur aufeinander warten, kannst du da auch normale Funktionsaufrufe draus machen.



  • Weiß nicht ob es dir hilft, aber schau dir mal die Funktionen

    SuspendThread()
    

    und

    ResumeThread()
    

    an


Anmelden zum Antworten