Mulithreading



  • Aus zwei zeilen Code laesst sich schlecht etwas ablesen.



  • ok hier der gesammt code wenn euch das hilft ^^

    //***************************************************************************
    //Headerdateien
    //***************************************************************************
    #include <windows.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdio.h>
    #include <conio.h>
    #include <process.h>
    #include <time.h>
    #include <iostream>
    #include <ShellAPI.h>
    #include "OmsUmxMC.h"
    #include "dlltyp.h"
    #include "regs.h"
    #include "spcerr.h"
    #include "spcm_drv.h"
    #include "spcm_lib_card.h"
    #include "spcm_lib_data.h"
    #include "spcm_oswrap.h"
    #include "spcm_ostools.h"
    //***************************************************************************
    //Defines
    //***************************************************************************
    #define ANZAHL_SPALTEN 16384	//Spalten	(Messwerte pro Messung)
    #define ANZAHL_ZEILEN 100		//Zeilen	(Anzahl der Messungen)
    #define SPALTENBREITE 10
    #define ANZAHL_ZEILENENDE 2
    #define MAX_THREADS  32
    #define getrandom( min, max ) (SHORT)((rand() % (int)(((max) + 1) - \ (min))) + (min))
    //***************************************************************************
    //Funktionsprototypen
    //***************************************************************************
    //int		main( void ); 
    int		main( int); // Thread 1: main 
    void	KbdFunc( void  );               // Keyboard input, thread dispatch
    void	ClearScreen( void );            // Screen clear 
    void	ShutDown( void );               // Program shutdown 
    void	WriteTitle( int ThreadNum );    // Display title bar information 
    void	stoppuhr( void *ch);
    void	vDoCardSetup (ST_SPCM_CARDINFO *pstCard);
    int16	nShowDigitalInputData (ST_SPCM_CARDINFO *pstCard, void* pvBuffer, uint32 dwNrOfSamplesToShow);
    int16	nShowAnalogData (ST_SPCM_CARDINFO *pstCard, void* pvBuffer,int k);
    int16	nShowDigitalData (ST_SPCM_CARDINFO *pstCard, void* pvBuffer, uint32 dwNrOfSamplesToShow);
    void	scan (void *pMyID);
    
    //void	scan ();
    int		scannen(int k);
    int		links();
    void	reset();
    void	fahren(void *pMyID);
    
    //void	fahren();
    int		initMesskarte();
    //***************************************************************************
    //Globale Variablen
    //***************************************************************************
    HANDLE  hConsoleOut;                 // Handle to the console 
    HANDLE  hRunMutex;                   // "Keep Running" mutex 
    HANDLE  hScreenMutex;                // "Screen update" mutex
    int     ThreadNr;                    // Number of threads started 
    CONSOLE_SCREEN_BUFFER_INFO csbiInfo; // Console information 
    char	ControllerModel[128] = {0};
    char    Response[128] = {0};
    HANDLE  OmsUmxHandle;
    long    PortNumber;
    long    BaudRate;
    int     Status = 0,		TimeLimit = 0;
    BOOL    Done;
    long    StatusFlags;
    int		zahl,			weiter = 1,		count = 0;
    char	teil2[]		= "120000";	//Länge der Drehung 
    char	teil1[25]	= "axmr+" ;//Achs- und Richtungsangabe //	-:hoch			+:runter
    char	teil3[]		= ";goid" ;//Startbefehl
    char	kette[50];
    short	wert[16384][100];
    int		a=0;
    int		b=0;
    
    	char                szBuffer[1024];     //Array zur Speicherung von Daten
        ST_SPCM_CARDINFO    stCard;             //Informationsstrucktur
        uint64              qwMemInBytes;
        void*               pvBuffer;
        int32               lValue;	
    
    //***************************************************************************
    //Main
    //***************************************************************************
    int main(int a) 
    {	
        ThreadNr = 0;
    
    	//Threads
    	int KeyInfo;
    	//initMesskarte();
    	do
       {
    		KeyInfo = _getch();
    		if ( tolower( KeyInfo ) == 'a' && ThreadNr < MAX_THREADS )
    		{	//Threads starten		
    			//_beginthread(scan	, 0	,	&ThreadNr );
    			//_beginthread(fahren	, 0	,	&ThreadNr );
    			_beginthread(scan	, 1	,	NULL );
    			SetThreadAffinityMask(scan,1); 
    			_beginthread(fahren	, 0	,	NULL );
    			SetThreadAffinityMask(fahren,2); 
    		}
    			//printf("%i",Done);
    	} while( tolower( KeyInfo ) != 'q' );//Fenster schließen
    
    	//while (Done!=1)
    	//{
    	//	while(Done==1)
    	//	{
    			//Datenspeicherung
    			FILE *fp=fopen("C:/Messergebnis.txt","w"); //Zieldatei
    			int s,z;	
    			for (s=0;s<ANZAHL_ZEILEN;s++)
    			{
    				for(z=0;z<ANZAHL_SPALTEN;z++)
    				{
    					fprintf(fp, "%*d", SPALTENBREITE,wert[z][s]);
    				}
    				fprintf(fp,"\n");
    			}
    	//	}
    	//}
    
    }
    //***************************************************************************
    //Funktionen
    //***************************************************************************
    void ShutDown( void ) // Shut down threads 
    {
        while ( ThreadNr > 0 )
        {
            // Tell thread to die and record its death.
            ReleaseMutex( hRunMutex );
            ThreadNr--;   
        }
        // Clean up display when done
        WaitForSingleObject( hScreenMutex, INFINITE );
        ClearScreen();
    }
    //
    void WriteTitle( int ThreadNum )
    {
        enum 
    	{ 
            sizeOfNThreadMsg = 80 
        };
        char    NThreadMsg[sizeOfNThreadMsg];
        sprintf_s( NThreadMsg, sizeOfNThreadMsg, " Start= 'A'  Beenden='Q'", ThreadNum );
        SetConsoleTitle( NThreadMsg );
    }
    //
    void ClearScreen( void )
    {
        DWORD    dummy;
        COORD    Home = { 0, 0 };
        FillConsoleOutputCharacter( hConsoleOut, ' ', csbiInfo.dwSize.X * csbiInfo.dwSize.Y, Home, &dummy );
    }
    //
    void fahren (void *pMyID)
    {	
    	//Motion Controller initialisieren
    	//PORT Nummer und Baudrate setzen
    	PortNumber = 3;
    	BaudRate = 9600;
    	reset();
    	//Überprüfung ob Controller erreichbar ist
    	Status = SendAndGetString(OmsUmxHandle, "wy", ControllerModel);
    	if(Status == SUCCESS)//Cotroller erreichbar
    	{
    		//printf("\n MC bereit! \n");
    	}
    	else	//Cotroller nicht erreichbar
    	{ 
    		printf("ERROR -----> Der Motion Controller antwortet nicht!!!\n");
    		CloseOmsUmxHandle(OmsUmxHandle);
    	}
    	//Stringerstellung zur Schrittanzahlübergabe
    	strcat_s(teil1,teil2);
    	strcat_s(teil1,teil3);
    	strcpy_s(kette,teil1);
    	links();
    }
    //
    void scan (void *pMyID)//void scan ()	
    {//Einstellung wieviele Messungen durchgeführt werden
    	for (int i=0; i<ANZAHL_ZEILEN; i++)
    	{		//printf("\n *");
    	//Anzahl der Messungen==ANZAHL_ZEILEN
    		scannen(i);	
    	}
    }
    //
    int initMesskarte()
    {	
    
        // Initialisierung der Messkarte
        if (bSpcMInitCardByIdx (&stCard, 0))
        {    
    		//printf (pszSpcMPrintCardInfo (&stCard, szBuffer, sizeof (szBuffer)));
    	}
        else
    	{
            return nSpcMErrorMessageStdOut (&stCard, "ERROR -----> Motion Controller kannnicht geöffnet weren\n", true);
    	}
        // Check ob Karte unterstützt wird 
        if (stCard.eCardFunction != AnalogIn && stCard.eCardFunction != DigitalOut && stCard.eCardFunction != DigitalIO)
    	{
            return nSpcMErrorMessageStdOut (&stCard, "Error\n", false);
    	}
        // Messkartensetup
        if (!stCard.bSetError)
    	{
            vDoCardSetup (&stCard);//Einstellung von Trigger/Samplerate/Offset etc
    	}
        // Allokiere Speicherbedarf
        if (!stCard.bSetError)
        {
            switch (stCard.eCardFunction)
            {
                case AnalogIn:
                    qwMemInBytes = stCard.llSetMemsize * stCard.lBytesPerSample * stCard.lSetChannels;     
                    break;
                case DigitalIO:
                    qwMemInBytes = stCard.llSetMemsize;     
                    break;
            }
           pvBuffer = (void*) new uint8[(int) qwMemInBytes];
            if (!pvBuffer)
                return nSpcMErrorMessageStdOut (&stCard, "ERROR -----> Speicherallokation\n", false);
        }
    }
    //
    int links()
    {	//Sleep(2000);
    
    	//Funktion fährt auf +90°//int links()
    	Status  = SendString(OmsUmxHandle, kette);		
    	if(Status == SUCCESS)
    	{
    		// Wait for a Done event, a Overtravel event or one second to pass 
    		TimeLimit = 5000;
    		do
    		{
    			Done = GlobalDoneEvent(OmsUmxHandle);
    			GetStatusFlags(OmsUmxHandle, &StatusFlags);
    			Sleep(10);
    			TimeLimit -= 10;
    		}
    		while (!Done && ((StatusFlags & OVERTRAVEL_ERROR) != OVERTRAVEL_ERROR) && (TimeLimit > 0)); 	
    		//if (Done==1)//DONE EVENT wenn befehl fertig ausgeführt worden ist
    		//{
    		//	
    			//a=1;
    			//ShutDown();
    			//return (a);
    		//}
    			// If the move did not time out 
    			if(TimeLimit > 0)
    			{
    				// If the move was successful 
    				if((StatusFlags & OVERTRAVEL_ERROR) != OVERTRAVEL_ERROR)
    				{
    					// Ask the controller for the new X axis position 
    					//Status = SendAndGetString(OmsUmxHandle, "axrp", Response);
    					if(Status == SUCCESS)
    					{
    						printf("\n  %s \n",Response);
    						CloseOmsUmxHandle(OmsUmxHandle);
    						return(0);
    					} 
    					else
    					{
    						printf("\nERROR -----> Der Motion Controller ist nicht in der Lage rechtzeitig aus die Abfrage zu reagieren\n");
    						CloseOmsUmxHandle(OmsUmxHandle);
    						return(1);
    					}}	
    				else // Report the overtravel 
    				{
    					printf("ERROR -----> Achsenüberlauf error\n");
    					CloseOmsUmxHandle(OmsUmxHandle);
    					return(1);
    				}}
    			else
    			{
    				printf("\nERROR -----> Timeout bevor die Bewegung fertig ausgeführt wurde\n");
    				CloseOmsUmxHandle(OmsUmxHandle);
    				return(1);
    			}}
    		else
    		{
    			printf("\nERROR -----> während des Senden des Bewegungsbefehls\n");
    			CloseOmsUmxHandle(OmsUmxHandle);
    			return(1);
    		}
    }
    //
    void reset()
    {//Resetet die gesetzten Werte
    	OmsUmxHandle = GetOmsUmxHandle(PortNumber, BaudRate);
    	if(OmsUmxHandle == (HANDLE)NULL)
    	{
    		printf("ERROR -----> Port ist nicht erreichbar!!! \n");
    	}
    	//Query the global done flag to set it false 
    	Done = GlobalDoneEvent(OmsUmxHandle);
    	//Clear all controller error status flags
    	ClrStatusFlags(OmsUmxHandle, (COMMAND_ERROR + SLIP_ERROR + OVERTRAVEL_ERROR));
    	// Command a relative move and request notification when the move is complete.
    }
    //
    int scannen (int k)
    {//eigentliche Funktion zu Aufnahme der Daten
        //char                szBuffer[1024];     //Array zur Speicherung von Daten
        //ST_SPCM_CARDINFO    stCard;             //Informationsstrucktur
        //uint64              qwMemInBytes;
        //void*               pvBuffer;
        //int32               lValue;	
        // Initialisierung der Messkarte
    
    	if (bSpcMInitCardByIdx (&stCard, 0))
        {    
    		//printf (pszSpcMPrintCardInfo (&stCard, szBuffer, sizeof (szBuffer)));
    	}
        else
    	{
            return nSpcMErrorMessageStdOut (&stCard, "ERROR -----> Motion Controller kannnicht geöffnet weren\n", true);
    	}
        // Check ob Karte unterstützt wird 
        if (stCard.eCardFunction != AnalogIn && stCard.eCardFunction != DigitalOut && stCard.eCardFunction != DigitalIO)
    	{
            return nSpcMErrorMessageStdOut (&stCard, "Error\n", false);
    	}
    
        // Messkartensetup
        if (!stCard.bSetError)
    	{
            vDoCardSetup (&stCard);//Einstellung von Trigger/Samplerate/Offset etc
    	}
        // Allokiere Speicherbedarf
        if (!stCard.bSetError)
        {
            switch (stCard.eCardFunction)
            {
                case AnalogIn:
                    qwMemInBytes = stCard.llSetMemsize * stCard.lBytesPerSample * stCard.lSetChannels;     
                    break;
                case DigitalIO:
                    qwMemInBytes = stCard.llSetMemsize;     
                    break;
            }
            pvBuffer = (void*) new uint8[(int) qwMemInBytes];
            if (!pvBuffer)
                return nSpcMErrorMessageStdOut (&stCard, "ERROR -----> Speicherallokation\n", false);
        }
    
        // Aquisitation und Daten holen
        if (!stCard.bSetError)
        {
            // Start der Karte und warte bis Karte bereit ist
    		spcm_dwSetParam_i32 (stCard.hDrv, SPC_TIMEOUT, 10000);
            //starte Karte und warte auf Interrupt: READY
    		if (spcm_dwSetParam_i32 (stCard.hDrv, SPC_M2CMD, M2CMD_CARD_START | M2CMD_CARD_ENABLETRIGGER | M2CMD_CARD_WAITREADY) == ERR_TIMEOUT)
            {
                delete [] ((uint8*) pvBuffer);
                return nSpcMErrorMessageStdOut (&stCard, "ERROR ----> Timeout\n", false);
            }
            else
            {
    
                // definiere Speicher für den Transfer  und Starte ihn
    			spcm_dwDefTransfer_i64	(stCard.hDrv, SPCM_BUF_DATA, SPCM_DIR_CARDTOPC, 0, pvBuffer, 0, qwMemInBytes);
                spcm_dwSetParam_i32		(stCard.hDrv, SPC_M2CMD, M2CMD_DATA_STARTDMA | M2CMD_DATA_WAITDMA);
                // Fehlercheck
    
                if (spcm_dwGetErrorInfo_i32 (stCard.hDrv, NULL, NULL, szBuffer))
                {
                    delete [] ((uint8*) pvBuffer);
                    return nSpcMErrorMessageStdOut (&stCard, szBuffer, false);
                }} }    
        // Aufteilen der Daten in die verschiedenen Kanäle
        if (!stCard.bSetError)
    
            switch (stCard.eCardFunction)
            {
                case AnalogIn:
    				do
    				{
    
                    spcm_dwGetParam_i32 (stCard.hDrv, SPC_READDIGITAL, &lValue);		//Messaufnahme
    
                    // Digitale Inputs gesetz?
    					if (lValue)
    					{
    						// Speicheralokation
    						void* pvAnalogData  = (void*) new uint8[(int) qwMemInBytes]; 
    						void* pvDigitalData = (void*) new uint8[(int) (qwMemInBytes / stCard.lBytesPerSample)];                    
    						// Aufsplitten der Daten in digital/analog
    						bSpcMSplitAnalogAndDigitalData (&stCard, pvBuffer, (uint32)(qwMemInBytes / stCard.lBytesPerSample), pvAnalogData, pvDigitalData);                    
    						// zeige Digitaledaten
    						nShowDigitalInputData (&stCard, pvDigitalData, 10);
    						// zeige Analogdaten
    						nShowAnalogData (&stCard, pvAnalogData,k);
    
                        }
                    else
                        nShowAnalogData (&stCard, pvBuffer,k);		//Darstellung
    
    				}while(Done!=1);
    
                    break;
                case DigitalIO:
                    nShowDigitalData (&stCard, pvBuffer, 10);  
                    break;
                }
        // Fehlermeldung
        if (stCard.bSetError)
    	{
    		return nSpcMErrorMessageStdOut (&stCard, "ERROR ----> Motion Controller kann nicht programmiert werden\n", true);
    	}
    
        // Speicher löschen und Karte schließen
        vSpcMCloseCard (&stCard);
    	//printf("\n geschlossen");
    
    	delete [] ((uint8*) pvBuffer);
    	//printf("\n gelöscht");
    
        return 1;
    }
    //
    void vDoCardSetup (ST_SPCM_CARDINFO *pstCard)
    {//vDoCardSetup
        int i;
        int64 llChannelMask;
        // Kanalmasken setzten
        if (pstCard->lMaxChannels >= 64)
            llChannelMask = -1; // -1 is all bits set to 1 = 0xffffffffffffffff
        else
            llChannelMask = ((int64) 1 << pstCard->lMaxChannels) - 1;
    
    	//Triggereinstellung
    	//	|<------Memsize------->|
    	//	|<--Pre--->||<--Post-->|
    	//bSpcMSetupModeRecStdSingle (pstCard,	llChannelMask,		MEMSIZE,	POSTTRIGGER;//original
        bSpcMSetupModeRecStdSingle (pstCard,	llChannelMask,		KILO_B(16), KILO_B(16));
    
    	// Samplerate 
        //bSpcMSetupClockPLL (pstCard, pstCard->lMaxSamplerate / 4, false); //original
    	bSpcMSetupClockPLL (pstCard, pstCard->lMaxSamplerate , false);
    	//bSpcMSetupClockPLL (pstCard, 1000000 , false);
    
    	//Triggereinstellungen (Software/Extern/Kanal)
    	//bSpcMSetupTrigSoftware (pstCard, false); //original				//Software
    	bSpcMSetupTrigExternal (pstCard, SPC_TM_POS);						//Extern USD15S
        //bSpcMSetupTrigChannel(pstCard,SPC_TRIG_CH0_MODE, SPC_TM_POS);		//Kanal
    
        switch (pstCard->eCardFunction)
            {
            case AnalogIn:
    			//Offset einstellen
                for (i=0; i < pstCard->lMaxChannels; i++)
    				//bSpcMSetupInputChannel (	pstCard, i,		OFFSET, true);
    				bSpcMSetupInputChannel (	pstCard, i,		10000,	true);
                   // bSpcMSetupPathInputCh (		pstCard, i, 0,		10000,	false, true, true); // setup for M3i card series including new features
                // aktiviere digitale Inputs
                if (pstCard->lFeatureMap & SPCM_FEAT_DIGITAL)
                    spcm_dwSetParam_i32 (pstCard->hDrv, SPC_READDIGITAL, 1);            
                break;
            case DigitalIn:
            case DigitalIO:
                // Eingangswiderstände setzetn
                for (i=0; i < pstCard->uCfg.stDIO.lGroups; i++)
                    bSpcMSetupDigitalInput (pstCard, i, true);
                break;
            }
        }
    //
    int16 nShowAnalogData (ST_SPCM_CARDINFO *pstCard, void* pvBuffer,int k)
    {//nShowAnalogData 
    
        int     i;
        double  dAverage;
        int16   nMin;
        int16   nMax;
        int16*  ppnChannelData[SPCM_MAX_AICHANNEL];
        // Kanaldaten
        for (i=0; i<pstCard->lSetChannels; i++)
        {
            ppnChannelData[i] = new int16[(int32) pstCard->llSetMemsize];
            if (!ppnChannelData[i])
    		{
                return nSpcMErrorMessageStdOut (pstCard, "ERROR -----> Speicherallokation\n", false);
    		}
        }   
        // Aufsplitten der Daten
        bSpcMDemuxAnalogDataToInt16 (pstCard, pvBuffer, (int32) pstCard->llSetMemsize, ppnChannelData);
        // Daten aus Speicher holen
       for (i=0; i<pstCard->lSetChannels; i++)
       {
            dAverage =dSpcMCalcAverage(ppnChannelData[0], (uint32) pstCard->llSetMemsize, k);	
    
       }
       for (i=0; i<pstCard->lSetChannels; i++)
       {
          delete [] (ppnChannelData[i]);
       }
    
        return 0;
    }
    //
    int16 nShowDigitalInputData (ST_SPCM_CARDINFO *pstCard, void* pvBuffer, uint32 dwNrOfSamplesToShow)
    {//nShowDigitalInputData 
        int32 lNrOfDigCh, lCh, lBitShift, i;
        uint32 dwSampleIdx;
        uint8 byDigMask, byBitVal;
        uint8* ppbyChannelData[SPCM_MAX_AICHANNEL];
        lNrOfDigCh = 16 - pstCard->uCfg.stAI.lResolution;
        // allocate channel data
        for (i = 0; i < pstCard->lSetChannels; i++)
            {
            ppbyChannelData[i] = new uint8[(int32)pstCard->llSetMemsize];
            if (!ppbyChannelData[i])
                return nSpcMErrorMessageStdOut (pstCard, "ERROR -----> Speicherallokation\n", false);
            }
        bSpcMDemuxDigitalInputDataToUInt8 (pstCard, pvBuffer, (int32)pstCard->llSetMemsize, ppbyChannelData);
        for (dwSampleIdx = 0; dwSampleIdx < dwNrOfSamplesToShow; dwSampleIdx++)
            {
            for (lCh = 0; lCh < pstCard->lSetChannels; lCh++)
                {
                byDigMask = ppbyChannelData[lCh][dwSampleIdx]; 	
                lBitShift = 0;
                do 
                    {
                    byBitVal  = byDigMask & 0x01;
                    byDigMask = byDigMask >> 1;
                    lBitShift++;
                    }while (lBitShift < lNrOfDigCh);
                }}
        for (i = 0; i < pstCard->lSetChannels; i++)
            delete [] (ppbyChannelData[i]);
        return 0;	
     }
    //
    int16 nShowDigitalData (ST_SPCM_CARDINFO *pstCard, void* pvBuffer, uint32 dwNrOfSamplesToShow)
    {//nShowDigitalData 
        int32 i, lChIdx;
        uint32 dwSampleIdx;
        int8* ppbyChannelData[SPCM_MAX_DIOCHANNEL];
        // allocate channel data
        for (i=0; i<pstCard->lSetChannels; i++)
        {
            ppbyChannelData[i] = new int8[(int32) pstCard->llSetMemsize];
            if (!ppbyChannelData[i])
                return nSpcMErrorMessageStdOut (pstCard, "ERROR -----> Speicherallokation\n", false);
        }
        bSpcMDemuxDigitalDataToInt8 (pstCard, pvBuffer, (int32) (pstCard->llSetMemsize), ppbyChannelData);
        for (dwSampleIdx=0; dwSampleIdx<dwNrOfSamplesToShow; dwSampleIdx++)
        {
                if (pstCard->lSetChannels < 16)
                {
                    lChIdx = pstCard->lSetChannels-1;
                    while (lChIdx >= 0)
                    {
                      // printf ("[D%d] = %d ", lChIdx, ppbyChannelData[lChIdx][dwSampleIdx]);
                        lChIdx--;
                    }
    
                    //printf ("\n\n");
                }
                else
                {
    				lChIdx = pstCard->lSetChannels-1;
                    while (lChIdx > 0)
                    {
                        //printf ("[D%d ......... D%d] ", lChIdx, lChIdx - 15);
                        lChIdx -= 16;
                    }
                    lChIdx = pstCard->lSetChannels-1;
                    while (lChIdx >= 0)
                    {
                        if (!(lChIdx%16))
    					{
    					}
                        else
    					{
                            if (!(lChIdx%4))
    						{
    						}
    					}
                        lChIdx--;
                    }}	}
        for (i=0; i<pstCard->lSetChannels; i++)
            delete [] (ppbyChannelData[i]);
        return 0;
    }
    


  • Reduziere den Quellcode bitte mal soweit, dass der Fehler immernoch auftritt 🙂



  • _beginthread(scan   , 1 ,   NULL );
                SetThreadAffinityMask(scan,1);
                _beginthread(fahren , 0 ,   NULL );
                SetThreadAffinityMask(fahren,2);
    

    wobei dies grade nur ein test ist normalerweise machen ich nur
    _beginthread(scan , 1 , NULL );
    _beginthread(fahren , 0 , NULL );



  • Nun, dein Quelltext ist nicht der beste.

    _beginthread(scan   , 1 ,   NULL ); 
    SetThreadAffinityMask(scan,1); 
    _beginthread(fahren , 0 ,   NULL ); 
    SetThreadAffinityMask(fahren,2);
    

    Schaue dir bitte an, wie diese Funktionen zu verwenden sind, insbesondere SetThreadAffinityMask! Im Zweifel, lass sie einfach weg. Tip: scan und fahren sind keine Thread-Handles.

    void scan (void *pMyID)//void scan ()   
    {//Einstellung wieviele Messungen durchgeführt werden 
        for (int i=0; i<ANZAHL_ZEILEN; i++) 
        {       //printf("\n *"); 
        //Anzahl der Messungen==ANZAHL_ZEILEN 
            scannen(i); 
        } 
    }
    

    Das sieht schon sehr komisch aus, auch deine Funktion scannen. Wie lange braucht sie, um ausgefuehrt zu werden?



  • also das problemliegt darin:

    sobald ich

    void scan (void *pMyID)
    {//Einstellung wieviele Messungen durchgeführt werden
        for (int i=0; i<ANZAHL_ZEILEN; i++)
        {       //printf("\n *");
        //Anzahl der Messungen==ANZAHL_ZEILEN
            scannen(i);
        }
    }
    

    in der funktion scannen rausnehme kann ich es ja nicht mehr kontrollieren.

    ich sehe nur an den messerbnissen die ich über matlab ausgeben das die bilder gemacht werden wenn der motor wieder steht.
    da ich immer fast gleiche werte messe..

    ich müsste allerdings starke veränderungen sehen wenn die messung während einer fahrt gemacht wird.

    die beiden tasks laufen also nicht gleichzeitig los... kann ich nicht einen task über einen kern laufen lassen und die andere task über einen andern kern.
    ich habe 2 Kerne also sollte es so ja funktionieren können.



  • knivil schrieb:

    Um ehrlich zu sein, du haettest mir viel Zeit und Raetselraten erspart, wenn du gleich mit mehr Information herausgerueckt waerst!

    _beginthread(scan   , 1 ,   NULL ); 
    SetThreadAffinityMask(scan,1); 
    _beginthread(fahren , 0 ,   NULL ); 
    SetThreadAffinityMask(fahren,2);
    

    Schaue dir bitte an, wie diese Funktionen zu verwenden sind, insbesondere SetThreadAffinityMask! Im Zweifel, lass sie einfach weg. Tip: scan und fahren sind keine Thread-Handles.

    ich habe ganz am anfang des themas doch gesagt das ich nur diese beiden Sachen nutze!!
    _beginthread(scan , 0 , &ThreadNr );
    _beginthread(fahren , 0 , &ThreadNr );


  • Mod

    servusundhallo schrieb:

    _beginthread(scan   , 1 ,   NULL );
                SetThreadAffinityMask(scan,1);
                _beginthread(fahren , 0 ,   NULL );
                SetThreadAffinityMask(fahren,2);
    

    Was bitte soll dieser Ober-Unfug?
    Meinst dadurch wird was "parallel"?
    Schmeiß das raus. Das macht alles nur noch schlimmer. Wieso glauben eigentlich immer viele Programmierer sie könnten Multitasking besser als das OS? 🙂

    Also:
    1. Warum sagst Du uns nicht, dass hier Hardware im Spiel ist?
    Haben Hardware von Fahren und Scannen was miteinander zu tun?
    2. Du wirfst in dem Thread fahren in 10msec (maximal) irgendwas raus und hoffst das ein anderer Thread was mitbekommt, der auch noch ungleich aufwendiger, sich erst mal einen Device besorgen muss?
    3. Ansonsten ist dieser Code für mich ein Graus. Toter Code ohne ende. Hast Du schon mal was von #ifdef gehört mit dem Man Testcode auskoppeln kann?



  • knivil schrieb:

    void scan (void *pMyID)//void scan ()   
    {//Einstellung wieviele Messungen durchgeführt werden 
        for (int i=0; i<ANZAHL_ZEILEN; i++) 
        {       //printf("\n *"); 
        //Anzahl der Messungen==ANZAHL_ZEILEN 
            scannen(i); 
        } 
    }
    

    Was meinst du wohl, wie lange es im Vergleich zur Comport-Kommunikation "fahren" braucht, diese Funktion auszufuehren?

    das geht sehr sehr schnell!!!!!
    ich sehe ja wie danach die bilder gemacht werden und wie schnell es geht..

    die messkarte kann das locker ^^

    die funktion fahren dauert ja auch en moment bis die fahrt fertig ist ^^ der motor beamt ja schließlich nicht

    nur während einer fahrt wird kein einziges bild gemacht !



  • HalloundServus schrieb:

    Thread 1: dauert länger (führt eine Bewegung über Motoren etc aus)
    Thread 2: soll Messungen machen

    (Seite 1 dieses Beitrages)

    habe ich bereits ganz am Anfang gesagt.

    ich habe nir behauptet das ich das kann ^^.. vielmehr hasse ich es ^^.. und von können kann keine rede sein
    es muss ja aber leider genutzt werden^^

    Ich habe vorher immer mit FreeRTOS das gemacht und im AVR Studio ^^ aber das in VS ist was ganz anderes!

    Nochmal zur Erklärung:
    also der Funktion fahren startet eine Bewegung.
    Während dieser Bewegung werden Messungen gemacht.
    Ich möchte einfach nur das beide starten etwa gleichzeitig und nicht nacheinander so das jetzt der Fall ist.

    .. mehr möchte ich ja gar net 😞



  • Warum ueberhaupt Threads? Nach dem Starten kann doch der Motor alleine Fahren.


  • Mod

    1. Ich kann lesen!
    2. Habe ich nicht behauptet, dass Du ein Könner bist/sein muss.
    3. Du behauptest Multithreading geht nicht!!! Defakto hast Du aber IMHO ein Verständnisproblem.

    Zurück zum Thema:
    Und wann ist die Bewegung zu Ende?
    Wie ich das sehe (meine persönliche unbedeutende Meinung) gibst Du einen Steuerungsstring aus über eine Serielle Schnittstelle. Und? Das dauert 10msec. (wenn es lange dauert).
    Dann erfolgt doch erst die Bewegung des Motors oder was auch immer.
    Wieso glaubst Du, dass das Senden auch erst beendet ist, wenn der Befehl ausgeführt wurde?

    @knivil: Bingo!!!

    Beispiel: Du bist Steuermann eines Tankers. Du reist das Ruder auf hartbackbord. Und Stellst nach 1 Sekunde fest, dass Dein Tanker leider immer noch geradeaus fährt. Wie kann das sein?

    PS: Wenn Dein Code in der anderen Umgebung (die Du beherrscht) genauso aussieht ist wohl nicht VS schuld. Just my 2 Cents.



  • mir ist klar dass das Senden schnell geht aber das Messen wird erst nach Beendigung der Bewegung durchgeführt.. das ist mein Problem


  • Mod

    servusundhallo schrieb:

    mir ist klar dass das Senden schnell geht aber das Messen wird erst nach Beendigung der Bewegung durchgeführt.. das ist mein Problem

    Und wo ist nun das Problem?
    Dan wird eben schnell gesendet und gemessen hinterher. Ist das ein Problem.
    Wenn Du erst messen und dann steuern willst dann sende verzögert, oder synchronisiere die Threads. Früher oder später musst Du sowieso Messen und Steuern koppeln vermute ich mal.

    Als Test: Warte mit dem Senden bis der Messthread 1 Sekunde läuft.

    BTW: Solange wir nicht wissen was Du eigentlich vor hast ist das alles hier akademisch.
    Du hast es eben hier mit asynchronen Vorgängen zu tun...



  • servusundhallo schrieb:

    mir ist klar dass das Senden schnell geht aber das Messen wird erst nach Beendigung der Bewegung durchgeführt.. das ist mein Problem

    Naja, dass kann viele Ursachen haben. Die Loesung ist aber nicht, Threads zu nutzen, sondern erstmal das Problem zu verstehen!

    spcm_dwSetParam_i32 (stCard.hDrv, SPC_TIMEOUT, 10000); 
    //starte Karte und warte auf Interrupt: READY 
    if (spcm_dwSetParam_i32 (stCard.hDrv, SPC_M2CMD, M2CMD_CARD_START | M2CMD_CARD_ENABLETRIGGER | M2CMD_CARD_WAITREADY) == ERR_TIMEOUT)
    

    Beispielsweise sagt diese Zeile, dass es 10sec dauern kann, bis die Messkarte initialisiert ist. Auch ist es wohl unnoetig bei jeder Messung die Karte neu zu initialisieren.



  • ich weiß nicht wie ich es noch erklären soll.

    Ich fahre mit dem Motor eine bestimmte Strecke während dieser Strecke soll 100mal gemessen werden.

    Ist:
    Fahren
    Fahren fertig
    100x messen

    Soll:
    Fahren+100mal messen



  • knivil schrieb:

    servusundhallo schrieb:

    mir ist klar dass das Senden schnell geht aber das Messen wird erst nach Beendigung der Bewegung durchgeführt.. das ist mein Problem

    Naja, dass kann viele Ursachen haben. Die Loesung ist aber nicht, Threads zu nutzen, sondern erstmal das Problem zu verstehen!

    spcm_dwSetParam_i32 (stCard.hDrv, SPC_TIMEOUT, 10000); 
    //starte Karte und warte auf Interrupt: READY 
    if (spcm_dwSetParam_i32 (stCard.hDrv, SPC_M2CMD, M2CMD_CARD_START | M2CMD_CARD_ENABLETRIGGER | M2CMD_CARD_WAITREADY) == ERR_TIMEOUT)
    

    Beispielsweise sagt diese Zeile, dass es 10sec dauern kann, bis die Messkarte initialisiert ist. Auch ist es wohl unnoetig bei jeder Messung die Karte neu zu initialisieren.

    hatte ich auch schon ausgelagert (initmesskarte)
    allerdings muss der buffer gelöscht werden die funktionierte dann nichtmehr und ich hatte immer die gleichenmesswerte gespeichert
    das Timeout gibt solange wartet die karte wenn bis dahin keine rückmeldung von der Messkarte kommt wird ein Fehler ausgegeben.



  • servusundhallo schrieb:

    Fahren+100mal messen

    Ich habe es begriffen.

    Beim Funktionsaufruf ging es mir darum: Was passiert mit deiner Messung, wenn die Initialisierung 5sec dauert? Keine Ahnung, kann das nicht Testen, ist deine Hardware.



  • hi

    also ich habe eine pause eingefügt in die Fahrfunktion

    egal wie lange ich diese einstelle Messung erst nach beendigung der Fahrt(jetzt ohne Threads)

    einfach nur

    fahren();
    messen();

    aufgerufen



  • do 
            { 
                Done = GlobalDoneEvent(OmsUmxHandle); 
                GetStatusFlags(OmsUmxHandle, &StatusFlags); 
                Sleep(10); 
                TimeLimit -= 10; 
            } 
            while (!Done && ((StatusFlags & OVERTRAVEL_ERROR) != OVERTRAVEL_ERROR) && (TimeLimit > 0));
    

    Weil du in der Fahrenfunktion wartest, bis er angekommen ist.
    wie waere es mit
    starteFahren();
    solange nicht fertig, messen();

    ich sehe nur an den messerbnissen die ich über matlab ausgeben das die bilder gemacht werden wenn der motor wieder steht.

    Woher weisst du, das es Bilder nach der Fahrt waren und nicht davor?


Anmelden zum Antworten