Mulithreading
-
benutzt dein "motor - thread" evtl irgendwelche funktionen die den thread an sich blockieren lassen (sprich positionierung oder sowas)?
-
hallo,
also die Idee mit dem auskommentieren hat funktioniert.
Es liegt irgendwie an dem Messthread.Der Fahrenthread läuft einwandfrei und blockiert eigentlich auch nix. Es waren vorher 2 einzelne Programme die nun kombiniert werden.
Eine Frage laufen Threads parallel oder nur quasiparallel?
Würde erklären warum immer nur eins von beidem ausgeführt wird.
Mein Test war :
beginthread(messen)
beginthread(fahren)in der funktion messen habe ich dann erstmal die Funktionen zum Messen auskommentiert und habe nur ein* ausgeben lassen.
Ergebnis:
Motor fährt und parallel werden * ausgegeben.Also muss es ja an der Messfunktion liegen.
Kann es evtl an einem Trigger liegen? Das die Messevents auslöst ?
-
Threads laufen parallel wenn Du einen Prozessor mit mehreren Kernen hast.
Die Ausgabe führt letzten Endesnatürlich auch zu einer Synchronisation weil diese auch immer nur für einen Thread zu einer zeit möglich ist.Was hast Du denn für Synchronisationsmethoden verwendet? Critical Sections Mutex???
Wodurch willst Du wissen, dass ein Thread nicht läuft?
-
Hallo,
ich sehe das der 2te Thread nicht läuft, da die Messergebnisse dies deutlich machen. sonst wäre mir das gar nicht aufgefallen.
Ich habe gar keine Synchromethodenverwendet.
Die Ausgabe war auch nur ein Test damit ich etwas auf der Konsole sehe.Zur Zeit ist es so:
Motor fährt danach werden die Messungen gemacht, obwohl ich zu erst den Messthread starte und danach den Motorthread.Ziel:
Starten von Motorthread
Starten von Messthread
= Messungen während der Bewegung sind möglich
-
1. Wie willst Du bitte ohne Threadsynchronisation etwas messen, was sich verändert?
2. Wenn Du keine Synchronisation verwendest dann laufen die Threads auch.
-
Die Threads laufen ja auch, allerdings leider nacheinander.
Die Messungen funktionieren auch allerdings werden die Bilder nach Beendigung der Bewegung gemacht.
Ich rufe die Threads jeweils mit
_beginthread(messen , 0 , NULL ); _beginthread(fahren , 0 , NULL );
auf.
Oder muss ich den Thread verschiedene Prios verteilen?
Oder was mit Mutex anstellen?Gibts nicht einfach so was wie
Starte Threads so das diese einfach nur anfangen zu laufen.
Ich benötige erstmal keine Synchro dazwischen, es greift auch keine auf die andere zu. Sie sollen einfach nur beide anfangen zu laufen und das wenns geht einigermaßen gleichmäßig.
Jetzt starten sie nacheinander bzw die 2te läuft erst dann weiter wenn die 1te zu Ende ist.
-
Dann besorge Dir einen langsameren Rechner.
Oder verwende Tasks die länger dauern...
-
-
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 );
-
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.
-
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.