Thread Probleme



  • Ich habe ein kleines Thread Problem, ich möchte zwei Threads starten und diese im Fenster ausgeben. Ich habe nur ein Problem, wenn ich das Programm starte, werden auch die Threads gestartet, nur werden sie nicht komplett ausgeführt. Zum Programm, wie schon in einem anderen Thema geschrieben, soll das Prog. die sqrt() von verschiedenen Zahlen 1 bis 49999 berechnen und ausgeben. Die Zahl wird aber nur bis 12000 oder etwas höher berechnet und der zweite Thread kommt etwa bis 8000. Weiter möchte ich gerne die Zeit ermitteln, aber ich verstehe das mit den Filetime-Strukturen und der Funktion GetThreadTime(), kann mir jemand helfen?

    Hier der gesamte Quelltext:

    #include "stdafx.h"
    #include "PDV3.h"
    #include "math.h"
    #include "stdio.h"
    #include <atlstr.h>
    #include <iostream>
    
    using namespace std;
    #define MAX_LOADSTRING 100
    
    // Globale Variablen:
    HINSTANCE hInst;								// Aktuelle Instanz
    TCHAR szTitle[MAX_LOADSTRING];					// Titelleistentext
    TCHAR szWindowClass[MAX_LOADSTRING];			// Klassenname des Hauptfensters
    DWORD WINAPI ThreadFunc1(LPVOID lpvThreadParam);
    DWORD WINAPI ThreadFunc2(LPVOID lpvThreadParam);
    
    Filetime 
    double zahl;
    double zahl1;
    double i;
    double i1;
    int a;
    CString strAusgabe;
    CString zahlausgabe;
    
    CString strAusgabe1;
    CString zahlausgabe1;
    
    void Wurzel (void) ;
    void Wurzel1 (void) ;
    
    ATOM				MyRegisterClass(HINSTANCE hInstance);
    BOOL				InitInstance(HINSTANCE, int);
    LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
    LRESULT CALLBACK	About(HWND, UINT, WPARAM, LPARAM);
    
    int APIENTRY _tWinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPTSTR    lpCmdLine,
                         int       nCmdShow)
    {
    	MSG msg;
    	HACCEL hAccelTable;
    	HANDLE hThread; 
    	DWORD dwThreadId; 
    
    	hThread = CreateThread( NULL, 0, ThreadFunc1, NULL, 0, &dwThreadId );
    
    	hThread = CreateThread( NULL, 0, ThreadFunc2, NULL, 0, &dwThreadId );
    
    	SetThreadPriority(ThreadFunc1,THREAD_PRIORITY_BELOW_NORMAL);
    	SetThreadPriority(ThreadFunc2,THREAD_PRIORITY_LOWEST);
    
    	SetThreadAffinityMask(ThreadFunc1,1);
    	SetThreadAffinityMask(ThreadFunc2,1);
    
    	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    	LoadString(hInstance, IDC_PDV3, szWindowClass, MAX_LOADSTRING);
    	MyRegisterClass(hInstance);
    
    	if (!InitInstance (hInstance, nCmdShow)) 
    	{
    		return FALSE;
    	}
    
    	hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_PDV3);
    
    	while (GetMessage(&msg, NULL, 0, 0)) 
    	{
    		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
    		{
    			TranslateMessage(&msg);
    			DispatchMessage(&msg);
    		}
    	}
    
    	return (int) msg.wParam;
    }
    
    ATOM MyRegisterClass(HINSTANCE hInstance)
    {
    	WNDCLASSEX wcex;
    	wcex.cbSize = sizeof(WNDCLASSEX); 
    
    	wcex.style			= CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
    	wcex.lpfnWndProc	= (WNDPROC)WndProc;
    	wcex.cbClsExtra		= 0;
    	wcex.cbWndExtra		= 0;
    	wcex.hInstance		= hInstance;
    	wcex.hIcon			= LoadIcon(hInstance, (LPCTSTR)IDI_PDV3);
    	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
    	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
    	wcex.lpszMenuName	= (LPCTSTR)IDC_PDV3;
    	wcex.lpszClassName	= szWindowClass;
    	wcex.hIconSm		= LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
    	return RegisterClassEx(&wcex);
    }
    
    BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    {
       HWND hWnd;
       hInst = hInstance; // Instanzenhandle in der globalen Variablen speichern
    
       hWnd = CreateWindow(szWindowClass, "Unterschiedlich priorisierte Threads", WS_OVERLAPPEDWINDOW,
          100, 100, 370, 330, NULL, NULL, hInstance, NULL);
    
       if (!hWnd)
       {
          return FALSE;
       }
       ShowWindow(hWnd, nCmdShow);
       UpdateWindow(hWnd);
    
       return TRUE;
    }
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	int wmId, wmEvent;
    	PAINTSTRUCT ps;
    	HDC hdc;
    
    	switch (message) 
    	{
    	case WM_COMMAND:
    		wmId    = LOWORD(wParam); 
    		wmEvent = HIWORD(wParam); 
    		switch (wmId)
    		{
    		case IDM_\1:
    			DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
    			break;
    		case IDM_EXIT:
    			DestroyWindow(hWnd);
    			break;
    		default:
    			return DefWindowProc(hWnd, message, wParam, lParam);
    		}
    		break;
    	case WM_PAINT:
    		hdc = BeginPaint(hWnd, &ps);
    		TextOut (hdc, 5, 10, "Identische Berechnungen von Thread 1 und 2", 42);
    		TextOut (hdc, 5, 30, "(Zeiten anfordern mit Mausdoppelklick)", 38);
    		TextOut (hdc, 5, 50, "==========================================", 42);
    		TextOut (hdc, 5, 90, "Thread 1 mit: THREAD_PRIORITY_BELOW_NORMAL",42);
    		TextOut (hdc, 5, 110,"Berechnungsergebnis:",20);
    		TextOut (hdc, 5, 130,"Gesamtlaufzeit in Millisekunden:",32);
    		TextOut (hdc, 5, 150,"Effektive Laufzeit:",19);
    		TextOut (hdc, 5, 190,"Thread 2 mit: THREAD_PRIORITY_LOWEST",36);
    		TextOut (hdc, 5, 210,"Berechnungsergebnis:",20);
    		TextOut (hdc, 5, 230,"Gesamtlaufzeit in Millisekunden:",32);
    		TextOut (hdc, 5, 250,"Effektive Laufzeit:",19);
    		EndPaint(hWnd, &ps);
    
    		hdc = GetDC(hWnd);
    		TextOut (hdc, 190, 110,zahlausgabe,5);
    		TextOut (hdc, 250, 110,strAusgabe ,12);
    		ReleaseDC(hWnd, hdc);
    
    		hdc = GetDC(hWnd);
    		TextOut (hdc, 190, 210,zahlausgabe1,5);
    		TextOut (hdc, 250, 210,strAusgabe1 ,12);
    		ReleaseDC(hWnd, hdc);
    
    		break;
    
    	case WM_LBUTTONDBLCLK:
    		MessageBox (hWnd, "Doppelklick der linken Maustaste erkannt", "Zeitausgaben anfordern",MB_ICONWARNING);
    		return 0;
    
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		break;
    	default:
    		return DefWindowProc(hWnd, message, wParam, lParam);
    	}
    	return 0;
    }
    
    LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	switch (message)
    	{
    	case WM_INITDIALOG:
    		return TRUE;
    
    	case WM_COMMAND:
    		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
    		{
    			EndDialog(hDlg, LOWORD(wParam));
    			return TRUE;
    		}
    		break;
    	}
    	return FALSE;
    }
    void Wurzel ()
    {	 
    	i=1.0;
     do
      {
    	  zahlausgabe.Format("%.0f", i);
    	  strAusgabe.Format("%.8f",zahl);
    	  zahl = sqrt (i+1);
    	  i++;
      }
      while (i < 50000);
    }
    
    void Wurzel1 ()
    {	 
    	i1=1.0;
     do
      {
    	  zahlausgabe1.Format("%.0f", i1);
    	  strAusgabe1.Format("%.8f",zahl1);
    	  zahl1 = sqrt (i1+1);
    	  i1++;
      }
      while (i1 < 50000);
    }
    
    DWORD WINAPI ThreadFunc1( LPVOID pParam ) 
    { 
    	Wurzel();
    
      return 0; 
    }; 
    
    DWORD WINAPI ThreadFunc2( LPVOID pParam ) 
    { 
    	Wurzel1();
    
      return 0; 
    };
    

    Vielleicht hat ja einer von euch eine Lösung.



  • du solltest besser für die threads besser keine globalen variablen verwenden. wenn schon, dann musste das synchronisieren, sonst ist dein code nur als zufallsgenerator zu gebrauchen 😉



  • Wenn du mir einen Tipp geben könntest wie ich das genau mache, wäre ich dir sehr dankbar, ich habe nämlich erst vor einer Woche mit C++ angefangen und habe da noch so meine Probleme mit.



  • Hi,

    wie bereits von net gesagt, wird es an den globalen CStrings liegen, die Du im Thread schreibst. Wahrscheinlich wird im Thread eine Access Violation auftreten, die zum Abschmieren des Threads selbst führt. Generell sollte man Threads synchonisieren, z.b. mit ::CreateEvent() einen Event anlegen und auf diesen mit ::WaitForSingleObject() mit Timeout abwarten. Am Besten schaust Du in der MSDN unter dem Thema "Multithreading Synchronization" nach. Threads sollten auch beim Beenden der Anwendung mit Events synchronisiert beendet werden, sonst schiesst Du den Thread einfach ab. Beim Speichern von Informationen oä könnte das fatal sein 🙂

    Dennis.



  • Und bitte die "C/C++" Tags benutzen.



  • Dieser Thread wurde von Moderator/in Unix-Tom aus dem Forum MFC mit dem Visual C++ in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.


Anmelden zum Antworten