Threads mit Hilfe von Event-Objects steuern



  • Hallo Zusammen,

    mein Programm beinhaltet zwei Threads. Nach einer bestimmten aktion sollte ThreadLesenPerson angehalten werden und ThreadLesenGeraet gestartet werden.
    Ich versuche es mit Hilfe von Event objects zu realisieren. Dabei werden beide threads mit einem Button gestartet. Sie warten dann auf "aktivierung" und laufen bis sie beenden werden. Thread laufen nich gleichzeitig. ThreadLesenGeraete startet wenn der erste Thread beendet wird.

    Mein Problemm: Ersten Thread anhalten und zweiten startet. Mit meinem Code (weiter unten skizziert) schaffe ich es nicht. Erste Thread hält nie an. Deshalb bitte um Hilfe, Hinweise und weblinks.

    UINT ThreadLesenPerson(LPVOID param)
    {
    	bool bTagread = false;
    	sSerNr = '0';
    	sError = '0';
    
    	::WaitForSingleObject(threadStart.m_hObject, INFINITE);
    
    	BOOL keepRunning = TRUE;
    	while (keepRunning)
    	{
    		int result = ::WaitForSingleObject(threadEnd.m_hObject, 0);
    		if (result == WAIT_OBJECT_0) 
    		{
    			keepRunning = FALSE;
    		}
    
    		//Funktion
    		Identification(sSerNr, bTagread, sError);
    
    		if(bTagread)
    		{
    			::PostMessage((HWND)param, WM_PERSID, 1, 0); // hier setze ich: threadStart.ResetEvent();
    		}												 // und: threadGerIdentStart.SetEvent();
    		else
    		{
    			::PostMessage((HWND)param, WM_PERSID, 0, 0);
    		}
    	}
    
    	return 0;
    }
    UINT ThreadLesenGeraet(LPVOID param)
    {		
    	bool bTagread = false;
    	sSerNr = '0';
    	sError = '0';
    
    	::WaitForSingleObject(threadGerIdentStart.m_hObject, INFINITE);
    
    	BOOL keepRunning = TRUE;
    	while (keepRunning)
    	{
    		int result = ::WaitForSingleObject(threadGerIdentEnd.m_hObject, 0);
    		if (result == WAIT_OBJECT_0) 
    				keepRunning = FALSE;
    
    		Identification(sSerNr, bTagread, sError);
    		if(bTagread)
    		{
    			::PostMessage((HWND)param, WM_GERID, 1, 0);
    		}
    		else
    		{
    			::PostMessage((HWND)param, WM_GERID, 0, 0);
    		}
    	}
    	return 0;
    }
    

    Vielen Dank im Voraus.


  • Mod

    Wenn die beiden Threads sowieso nicht gleichzeitig sondern nacheinander laufen, wieso kannst Du nicht alles in einen Thread packen?

    Wenn niemand die endThread Events setzt wird auch keiner der Threads beendet werden.
    Ich kan an Deinen Threads nicht erkennen woher Sie Ihre Informationen beziehen und vor allem was sie eigentlich tun. Die Laufzeitdaten ändern sich ja in diesem Code nicht. Wer setzt den die Daten? Wer setzt die Events?



  • erstmals danke für die Anwort.

    Alles in einen Thread packen - daran habe ich auch grad eben gedacht. Das werde ich auch machen. Später.

    So sieht die Struktur meines Progs aus:

    /*****************************************************************************
    *
    * Threads global
    *
    *****************************************************************************/
    UINT ThreadLesenPerson(LPVOID param)
    {
    	bool bTagread = false;
    	sSerNr = '0';
    	sError = '0';
    
    	::WaitForSingleObject(threadStart.m_hObject, INFINITE);
    
    	BOOL keepRunning = TRUE;
    	while (keepRunning)
    	{
    		int result = ::WaitForSingleObject(threadEnd.m_hObject, 0);
    		if (result == WAIT_OBJECT_0) 
    		{
    			keepRunning = FALSE;
    		}
    
    		//Funktion
    		Identification(sSerNr, bTagread, sError);
    
    		if(bTagread)
    		{
    			::PostMessage((HWND)param, WM_PERSID, 1, 0); 
    		}												 
    		else
    		{
    			::PostMessage((HWND)param, WM_PERSID, 0, 0);
    		}
    	}
    
    	return 0;
    }
    UINT ThreadLesenGeraet(LPVOID param)
    {		
    	bool bTagread = false;
    	sSerNr = '0';
    	sError = '0';
    
    	::WaitForSingleObject(threadGerIdentStart.m_hObject, INFINITE);
    
    	BOOL keepRunning = TRUE;
    	while (keepRunning)
    	{
    		int result = ::WaitForSingleObject(threadGerIdentEnd.m_hObject, 0);
    		if (result == WAIT_OBJECT_0) 
    				keepRunning = FALSE;
    
    		Identification(sSerNr, bTagread, sError);
    		if(bTagread)
    		{
    			::PostMessage((HWND)param, WM_GERID, 1, 0);
    		}
    		else
    		{
    			::PostMessage((HWND)param, WM_GERID, 0, 0);
    		}
    	}
    	return 0;
    }
    /******************************************************************************
    *
    * START
    *
    ******************************************************************************/
    void CBerwachungderMessgerteDlg::OnButtonStart() 
    { 
    
    	bool ReaderReady = false;
    	UpdateData(TRUE);
    
    	ReaderReady = DetectReader();
    	if(ReaderReady)//Reader ist betriebsbereit
    	{
    		if(ThreadIsStarted)
    		{
    			DeleteReader();
    			m_Start.SetWindowText("&Start");
    			threadEnd.SetEvent();
    			ThreadIsStarted = false;
    			CEdit *Edtext = (CEdit *) GetDlgItem(IDC_EDIT_START_INFO); 
    		}
    		else
    		{
    			//CWaitCursor wait;
    			m_Start.SetWindowText("&Stop");
    			//threadStart.SetEvent();
    			threadGerIdentStart.SetEvent();
    			HWND hWnd = GetSafeHwnd();
    			AfxBeginThread(ThreadLesenPerson, hWnd, THREAD_PRIORITY_NORMAL);
    			AfxBeginThread(ThreadLesenGeraet, hWnd, THREAD_PRIORITY_NORMAL);
    			ThreadIsStarted = true;
    		}
    	}
    	else//Reader nicht angeschlossen
    	{
    		GetDlgItem(IDC_EDIT_START_INFO)->SetWindowText("Reader anschließen");
    		//hintergurnd in ROT färben
    		m_Edt_StartInfo.SetBackColor(RGB(255,0,0));
    		return;
    	}
    
    }	
    /*****************************************************************************
    *
    * Thread Person Identifizierung
    *
    *
    *****************************************************************************/
    LONG CBerwachungderMessgerteDlg::PersID(WPARAM wParam, LPARAM lParam)
    {						
    
    	bool readFile = true;
    	CString	info = '0';
    	fstream PersFile;
    	char zeile[80];
    	char datSerNr[16];
    	int i=0;
    
    	datSerNr[0]='\0';
    
    	//wenn Kein Tag gefunden
    	if(wParam == 0)
    	{
    		GetDlgItem(IDC_EDIT_START_INFO)->SetWindowText("Bitte anmelden");
    		m_Edt_StartInfo.SetBackColor(RGB(80,100,245));
    		m_Edt_MemberInfo = "Um sich anzumelden, ID-Karte in die Nähe des Readers bringen";
    
    		m_Edt_BuchInfo.SetBackColor(RGB(192, 200, 200));
    		m_Btn_Buchen.EnableWindow(FALSE);
    		m_Edt_BuchInfo.EnableWindow(FALSE);
    		m_sBuchInfo = " ";
    		m_sKommentar = " ";
    	}
    	else
    	{	
    		//Datei öffnen
    		PersFile.open("Autorisierte Personen.txt", ios::in);
    
    		//zeilenweise Auslesen 
    		//wenn ID gefunden oder FileEnde dann stop
    		while(readFile & !PersFile.eof())
    		{	
    			PersFile.getline(zeile, 80);
    
    			info = zeile;	
    			strcpy(datSerNr, zeile);
    			datSerNr[16] = '\0';
    
    			//Wenn ID aus der Datei mit ID des gelesenen TAGs übereinstimmen
    			//D.h. autorisierte Person identifiziert 
    			if(datSerNr == sSerNr)
    			{
    				readFile = false;
    				GetDlgItem(IDC_EDIT_START_INFO)->SetWindowText("Anmeldung OK");
    				//hintergurnd in GRÜN färben, Info im Fester ausgeben
    				m_Edt_StartInfo.SetBackColor(RGB(0,255,0));
    				m_Edt_MemberInfo = info;
    
    				//m_Btn_Buchen.EnableWindow(TRUE);
    				//m_Edt_Kommentar.EnableWindow(TRUE);
    				//m_sKommentar ="Kommentar hier einfügen";
    
    				//Fenster Buchinfo einschalten und Infos darstellen
    				m_Edt_BuchInfo.EnableWindow(TRUE);
    				CEdit *GerInfoText = (CEdit *) GetDlgItem(IDC_EDIT_GERAETINFO); 
    				GerInfoText->SetFont(&FGerInfo); 
    				m_sBuchInfo = "Messgerät identifizieren";
    				m_Edt_BuchInfo.SetBackColor(RGB(80,150,255));
    
    				//ersten Thread anhalten
    				//threadStart.ResetEvent();
    
    				//zweiten Thread starten
    				//threadGerIdentStart.SetEvent();
    			}
    			else
    			{
    				readFile = true; // weiter nach ID in der .txt Datei suchen
    				GetDlgItem(IDC_EDIT_START_INFO)->SetWindowText("nicht autorisiert");
    				m_Edt_StartInfo.SetBackColor(RGB(255,0,0));
    				m_Edt_MemberInfo = "Sie versuchen sich mit nicht autorisierter ID-Karte anzumelden";
    
    				m_Btn_Buchen.EnableWindow(FALSE);
    				m_Edt_BuchInfo.EnableWindow(FALSE);
    				m_sKommentar =" ";	
    			}	
    		}
    
    		PersFile.close();	
    	}
    	UpdateData(FALSE);
    	return 0;
    }	
    /*****************************************************************************
    *
    * Thread Person Identifizierung
    *
    *	-	wParam = 0 -> kein Tag gelesen
    *	-	wParam = 1 -> Tag wurde gelesen
    *
    *****************************************************************************/
    LONG CBerwachungderMessgerteDlg::GerID(WPARAM wParam, LPARAM lParam)
    {	
    	bool bTagread = false;
    	bool readFile = true;
    	CString	zeilentext = '0';
    	fstream GerListFile;
    	char zeile[150];
    	char datGerSerNr[16];
    	char GerDaten[100];
    	int i = 0;
    	int a = 0;
    	int j = 0;
    
    	datGerSerNr[0]='\0'; //SerienNummer des GeräteTags aus der Datei
    
    	UpdateData(TRUE);
    
    	//Tag nicht gelesen
    	if(wParam == 0)
    	{
    		GetDlgItem(IDC_EDIT_BUCHINFO)->SetWindowText("fehler!");
    		//hintergurnd in ROT färben
    		m_Edt_BuchInfo.SetBackColor(RGB(255,0,0));
    		m_sKommentar = sError;
    
    	}
    	//Tag gelesen
    	else
    	{		
    		//GerätListe.txt Datei öffnen
    		GerListFile.open("GerätListe.txt", ios::in);
    
    		//zeilenweise Auslesen 
    		//wenn ID gefunden oder FileEnde dann stop
    		while(readFile & !GerListFile.eof())
    		{	
    			//zeilenweise GerätListe.txt lesen
    			GerListFile.getline(zeile, 150);
    
    			//zeilentext ist die gesamt gespeicherte information über messgerät
    			zeilentext = zeile;	
    			strcpy(datGerSerNr, zeile);
    			datGerSerNr[16] = '\0';
    
    			//Wenn ID aus der Datei mit ID des gelesenen TAGs übereinstimmen
    			if(datGerSerNr == sSerNr)
    			{
    				//Nur Bezeichnung, Gerätart, Hersteller aus der Datei hollen
    				//Diese Infos liegen genau zw 5ten und 8ten Semicollon
    				int l = strlen(zeilentext);	
    				for(i=0; i<l; i++)
    				{
    					if (zeilentext[i]==';') a++;
    
    					if (a >= 5 && a < 8) 
    					{
    						GerDaten[j] = zeilentext[i+1];
    						if(GerDaten[j]==';') GerDaten[j]=',';
    						j++;
    					}
    
    					if(a == 8) GerDaten[j-1]=0;
    				}
    				readFile = false;
    				//hintergurnd in GRÜN färben
    				m_Edt_BuchInfo.SetBackColor(RGB(0,255,0));
    				m_sBuchInfo = GerDaten;
    				m_sGerInfo = "Gerät identifiziert. Warte auf Buchung...";
    				threadGerIdentEnd.SetEvent();
    			}
    
    			//sonst weitersuchen
    			else
    			{
    				readFile = true;
    				m_sBuchInfo = "Fehler";
    				m_Edt_BuchInfo.SetBackColor(RGB(255,0,0));
    				m_sKommentar = "Dieser ID-Karte ist kein Gerät zugewiesen";	
    			}	
    		}
    
    		GerListFile.close();	
    	}
    
    	UpdateData(FALSE);
    	return 0;
    
    }
    


  • das Programm sollte folgendes können:
    1.Identifizierung der Person
    2.Idnetifizierung des Gerätes
    Zeitliche Abfolge:
    wenn 1. fertig -> 2.
    wenn 2. fertig -> user action -> 1. usw.

    bisher kann es aber nur Punkt 1. problemmlos ausgeführt werden.

    Fragen:
    a) Thread anhalten (ohne benutzung von sleep oder ähnlichem)
    b) Eventobjekt wieder als unsignaled setzen, nachdem es durch SetEvent() als signaled markiert wurde. mit ResetEvent()??

    vielen Dank für eure Unterstützung



  • Problem anderweitig gelöst.

    vielen Dank fürs Lesen.


Anmelden zum Antworten