Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.de  
   
Forentreff 2012     
Bücher-Shop mit Amazon (Buchkategorien)C++ : Referenzen zu C++ : C++ Builder : Visual C++ : C# : Java : Spieleprogrammierung : Systemprogrammierung Linux : Software-Entwicklung : .NET : Compilertechnik : Algorithmen & Datenstrukturen : Objektorientierung : Entwurfsmuster : UML : eXtreme Programming : Scrum : Projektmanagement : Software-Testing : Datenbanken : Tom DeMarco : Dilbert : User Friendly
C/C++ Forum :: MFC (Visual C++) ::  MFC Dialog im laufenden Prozess beenden OHNE Multithreading     Zeige alle Beiträge auf einer Seite Auf Beitrag antworten
Autor Nachricht
KPY3EP
Unregistrierter




Beitrag KPY3EP Unregistrierter 17:22:50 23.01.2012   Titel:   MFC Dialog im laufenden Prozess beenden OHNE Multithreading            Zitieren

Hallo,

Hab da n kleines Problem. Hab ein Windows Xp mit RTX für nen Versuchsaufbau. "Dank" der echtzeiterweiterung (die ich unbedingt benötige) verwaltet Windos aber nicht mehr die Threads, sondern eben die RTX. Fazit, auch schon ausprobiert, Multithreading funktioniert nicht.

Nun möchte ich aber einen Laufenden Testdurchlauf auch kontrolliert beenden können, da so ein Testdurchlauf mehrere Tage gehen kann.

Ich habe auch schon einen Tip bekommen, irgendwie mittels Netzwerk-Interrupt o.ä., jedoch entzieht sich das meiner (er)kenntnis....

Hätte da eventuell jemand einen Denkanstoß? Danke schonmal ;)
7x7-7
Mitglied

Benutzerprofil
Anmeldungsdatum: 04.08.2009
Beiträge: 28
Beitrag 7x7-7 Mitglied 00:52:45 25.01.2012   Titel:   Thread muss sich selbst beenden können            Zitieren

Hallo,

also wenn Du einen Prozess in einem Thread am Laufen hast, dann muss die Abbruchbedingung vom Thread aus ausgeführt werden - also der Thread muss sich selber beenden, da nach Threadstart kein Zugriff auf den Thread mehr möglich ist (meines Wissens nach) – der Thread kann aber auf die Steuersoftware zugreifen. Ich habe ein ähnlich gelagertes Problem daher immer so gelöst, dass der Thread ein bool, welches in der Steuersoftware definiert ist, in definierten Zeitabständen abruft. Je nachdem, ob das bool false oder true ist, weiß der Thread, ob er sich beenden soll oder nicht. Das bool kann man dann von der Steuersoftware aus beliebig setzen. Vielleicht kannst Du ja damit etwas anfangen.

MfG
Martin Richter
Moderator

Benutzerprofil
Anmeldungsdatum: 18.04.2006
Beiträge: 13520
Beitrag Martin Richter Moderator 08:46:47 25.01.2012   Titel:              Zitieren

Multithreading funktioniert nicht ist Quatsch. Wie kommst Du darauf?

Ansonsten kannst Du in Deinem Programm ein Named-Event abfragen, dass von einem externen Programm gesetzt werden kan. Dann würde dies das Ende des Tests anzeigen...

_________________
Martin Richter (MVP für C++) WWJD http://blog.m-ri.de
"A well-written program is its own heaven; a poorly written program is its own hell!" The Tao of Programming
KPY3EP
Unregistrierter




Beitrag KPY3EP Unregistrierter 10:27:54 25.01.2012   Titel:              Zitieren

Ich habe es ausprobiert...es funktioniert nicht.

Auf einem System ohne RTX funktioniert das Programm sehrwohl mit Multithreading. Sobald ich die RTX lade nicht mehr.

Vielleicht noch soviel: Es handelt sich um ein Dialog-Basierendes Programm, in welchen iich einen neuen Dialog starte mit Progressbar und Start/Stop Button usw. und natürlich setze ich schon mit dem Startbutton eine "flag" und nehme die mit dem Stop wieder "weg" (haha...).

Nunja, vermutlich lassen sich die Threads noch irgendwie in der Priorität derer der RTX anpassen, damit es wieder läuft. Bin grad dabei dies zu erkunden, dachte jemand hätte einen alternativvorschlag.
Martin Richter
Moderator

Benutzerprofil
Anmeldungsdatum: 18.04.2006
Beiträge: 13520
Beitrag Martin Richter Moderator 10:48:05 25.01.2012   Titel:              Zitieren

Was funktioniert nicht?
Was sagt GetLastError?
Was für Code führst Du aus?

Da Du vermutlich den Explorer auf Deinem Rechner starten kannst ist eswohl ein 100% Beweis, dass Multithreading funktioniert... ;)

_________________
Martin Richter (MVP für C++) WWJD http://blog.m-ri.de
"A well-written program is its own heaven; a poorly written program is its own hell!" The Tao of Programming
KPY3EP
Unregistrierter




Beitrag KPY3EP Unregistrierter 11:57:07 25.01.2012   Titel:              Zitieren

Bisschen zusammengefasst....ich starte halt ganz normal nen workerthread
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void CThreadexampleDlg::OnButtonStart()
{
cancelflag=0;
    GetDlgItem(IDC_BUTTON_START)->EnableWindow(false);
    AfxBeginThread(ThreadFunktion,this);
    UpdateData(TRUE);
}
void CThreadexampleDlg::OnButtonStop()
{
    cancelflag=1;
    UpdateData(TRUE);
}
UINT CThreadexampleDlg::ThreadFunktion(LPVOID pParam)
{
  CThreadexampleDlg* pMeineKlasse = (CThreadexampleDlg*)pParam;
  pMeineKlasse->Funktion();
  pMeineKlasse->GetDlgItem(IDC_BUTTON_START)->EnableWindow(true);
  return 0;
}
void CThreadexampleDlg::Funktion()
{
//hier läuft der Test ab...samt Fortschrittsbalken etc...
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void CThreadexampleDlg::OnButtonStart()
{
cancelflag=0;
GetDlgItem(IDC_BUTTON_START)->EnableWindow(false);
AfxBeginThread(ThreadFunktion,this);
UpdateData(TRUE);
}
void CThreadexampleDlg::OnButtonStop()
{
cancelflag=1;
UpdateData(TRUE);
}
UINT CThreadexampleDlg::ThreadFunktion(LPVOID pParam)
{
CThreadexampleDlg* pMeineKlasse = (CThreadexampleDlg*)pParam;
pMeineKlasse->Funktion();
pMeineKlasse->GetDlgItem(IDC_BUTTON_START)->EnableWindow(true);
return 0;
}
void CThreadexampleDlg::Funktion()
{
//hier läuft der Test ab...samt Fortschrittsbalken etc...
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void CThreadexampleDlg::OnButtonStart()
{
cancelflag=0;
    GetDlgItem(IDC_BUTTON_START)->EnableWindow(false);
    AfxBeginThread(ThreadFunktion,this);
    UpdateData(TRUE);
}
void CThreadexampleDlg::OnButtonStop()
{
    cancelflag=1;
    UpdateData(TRUE);
}
UINT CThreadexampleDlg::ThreadFunktion(LPVOID pParam)
{
  CThreadexampleDlg* pMeineKlasse = (CThreadexampleDlg*)pParam;
  pMeineKlasse->Funktion();
  pMeineKlasse->GetDlgItem(IDC_BUTTON_START)->EnableWindow(true);
  return 0;
}
void CThreadexampleDlg::Funktion()
{
//hier läuft der Test ab...samt Fortschrittsbalken etc...
}


Läuft auch alles prima auf dem PC ohne RTX. D.h. ich kann den Stop-Button betätigen während der Test läuft, und es hält an.
Mit RTX allerdings ist es so, dass ich den Stop Button nicht betätigen kann, ab und zu allerdings scheint er sich betätigen zu lassen (wenn man lange drauf drückt und den Zeitpunkt erwischt, zu dem er ansprechbar ist). Bestätigt meine vermutung, dass die RealtimeUmgebung die Threads handelt, und nicht Windows...

So, ich weiß nicht ob ich es nicht richtig verstehe, aber meiner Meinung nach startet die RTX im Windows einen eigenen Thread, welche eine höhere Priorität hat als Win selbst, um Echtzeitvorgänge zu ermöglichen. Ist es denn überhaupt möglich in dem RTX-Thread noch einen Thread zu starten?! Die Doku lässt mich darüber im unklaren, oder ich kapiers einfach nicht... :(
Martin Richter
Moderator

Benutzerprofil
Anmeldungsdatum: 18.04.2006
Beiträge: 13520
Beitrag Martin Richter Moderator 13:29:23 25.01.2012   Titel:              Zitieren

Damit führst Du alle UI Operationen aus dem zweiten Thread aus, damit werden lauter Threadsynchronisationen durchgeführt.
Das ist lahm ohne Ende...

Aber grundsätzlich: Solage im Thread1 die MessagePump läuft ist alles gut. Sollte die aber icht mehr laufen, dann hast Du einen vollen Deadlock, alleine schon durch den Progressbar.

_________________
Martin Richter (MVP für C++) WWJD http://blog.m-ri.de
"A well-written program is its own heaven; a poorly written program is its own hell!" The Tao of Programming
hustbaer
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.10.2006
Beiträge: 13529
Beitrag hustbaer Mitglied 15:26:23 25.01.2012   Titel:              Zitieren

Klingt für mich klar nach einem Anwendungsfehler.
Entweder dein Realtime-Zeugs müllt das irgendwie System zu (mit DPCs oder was auch immer), oder du lastest alle Cores mit "realtime" Threads aus oder irgend etwas in der Art.

Alleine dass du auf einem auf Realtime modifizierten Windows noch normale Windows Programme starten kannst, zeigt doch schon, dass multithreading kein Problem ist.
Oder meinst du alle "normalen" Windows Programme würden nur einen Thread verwenden? Dann blende mal die "Thread Count" Spalte im Taskmanager ein und wunder dich :)

_________________
"Let there be Licht..." http://lichttools.sourceforge.net/
Sehr cooles ASCII Spiel (leider nicht von mir): ASCII-Scramble - http://www.roskakori.at/ascii/
KPY3EP
Unregistrierter




Beitrag KPY3EP Unregistrierter 15:39:33 25.01.2012   Titel:              Zitieren

ja sicher. Das ist mir vollkommen klar. Aber so verhält sich es eben nicht mehr, sobald ein RTX-Prozess gestartet wurde...

Ich glaub wir reden anneinander vorbei (@hustbaer)

@Martin Richter:

Ja, lahm ist es ;) Aber wie geht es besser? Steck da nicht so drin...

Hab jetz übrigens etwas an der RTX rumgespielt, und wohl eine Option gefunden das Threading im zusammenhang mit Echtzeit-Prozessen zu ermöglichen. Zumindest funktioniert jetzt mein obiger Ansatz. Würde dennoch gern wissen, wie man einen solchen Thread "besser" gestaltet. :confused:
Martin Richter
Moderator

Benutzerprofil
Anmeldungsdatum: 18.04.2006
Beiträge: 13520
Beitrag Martin Richter Moderator 20:37:41 25.01.2012   Titel:              Zitieren

UI Nur im Mainthread... Der Worker posted höchstens mal eine Info über den Fortschritt.

_________________
Martin Richter (MVP für C++) WWJD http://blog.m-ri.de
"A well-written program is its own heaven; a poorly written program is its own hell!" The Tao of Programming
KPY3EP
Unregistrierter




Beitrag KPY3EP Unregistrierter 11:13:55 01.02.2012   Titel:   GetParent im Thread wie umgehen?            Zitieren

Hi ich nochmal.

Hab jetzt folgendes Problem im weiteren Verlauf. Das mit dem Multithreading hat sich nun dahingehend geklärt das ein Update der RTX erforderlich war um dies zu ermöglichen. Also alles gut.

Nun Starte ich einen Dialog, welcher einen Child-Dialog startet. In dem Child-Dialog starte ich einen Workerthread (obiger Code) in welchem ich allerdings auf Methoden des Parent-Dialogs zugreifen möchte.

C/C++ Code:
ParentDlg* parDlg = (ParentDlg*)GetParent();
C/C++ Code:
ParentDlg* parDlg = (ParentDlg*)GetParent();
C/C++ Code:
ParentDlg* parDlg = (ParentDlg*)GetParent();


funktioniert zwar soweit, jedoch benötige ich den vorher in den Membervariablen enthaltenen Inhalt...

So wie ich das verstehe, erstelle ich eine neue Instanz des Parent-Dialogs, der keinen Bezug mehr auf den "original"-Dialog hat, und alle variablen "Quark" enthalten...

Hab dazu folgendes entdeckt, der auch das gleiche Problen hatte...allerdings Check ich es nicht ganz, wie hier das Problem gelöst werden kann.

http://www.c-plusplus.de/forum/74846

Bin für jede Hilfe dankbar :idea:
Martin Richter
Moderator

Benutzerprofil
Anmeldungsdatum: 18.04.2006
Beiträge: 13520
Beitrag Martin Richter Moderator 11:23:58 01.02.2012   Titel:              Zitieren

Und warum übergibst Du nicht einfach einen Zeiger auf das Parent?

Sobald Du irgend etwas machst, dass ein Window Handle in dem anderen Thread benutzt aus Deinem CDialog fliegt Dir die Funktion um die Ohren. Window Handles und Windows Objekte sind threadlokal.

Warum baust Du keine neutrale Struktur mit den Daten, die sowohl der Thread als auch der Dialog benutzt?

_________________
Martin Richter (MVP für C++) WWJD http://blog.m-ri.de
"A well-written program is its own heaven; a poorly written program is its own hell!" The Tao of Programming
KPY3EP
Unregistrierter




Beitrag KPY3EP Unregistrierter 11:30:21 01.02.2012   Titel:              Zitieren

Zitat:
Und warum übergibst Du nicht einfach einen Zeiger auf das Parent?


Wie sähe das aus? Also ich rufe in dem Workerthread eine Memberfunktion des Parent auf. In dieser werden die Membervariablen selbiger verwendet, dort benötige ich aber den, vorher beim start des Programms, geladenen Inhalt.

Zitat:
Warum baust Du keine neutrale Struktur mit den Daten, die sowohl der Thread als auch der Dialog benutzt?


Mangelnde Erfahrung? Keine Ahnung wie sowas aussehen muss...bin noch relativ unerfahren. Wäre das dann so eine Art Globale Variablendeklaration??
merano
Mitglied

Benutzerprofil
Anmeldungsdatum: 21.12.2006
Beiträge: 231
Beitrag merano Mitglied 21:11:10 01.02.2012   Titel:              Zitieren

C/C++ Code:
AfxBeginThread (StartThread, param);
C/C++ Code:
AfxBeginThread (StartThread, param);
C/C++ Code:
AfxBeginThread (StartThread, param);


http://www.codeproject.com/Articles/2459/Using-AfxBeginThread-with-class-member-controlling
KPY3EP
Mitglied

Benutzerprofil
Anmeldungsdatum: 01.02.2012
Beiträge: 3
Beitrag KPY3EP Mitglied 12:25:44 02.02.2012   Titel:              Zitieren

Ok, Danke erstmal...aber weiter bringt mich das auch nicht. Vorteile Gegenüber der Vorhergehenden Variante ergeben sich nicht, denn das was ich brauche funktionier immer noch nicht.

Also, ich zeig erstmal was ich jetzt Testweise gemacht habe.

Ein Dialog erstellt namens CTreadTestDlg.

C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12
void CTreadTestDlg::TestFunktion()
{
    int Test = m_iAdrBits;
    m_iAdrBits++;
}

void CTreadTestDlg::OnButtonstartdlg()
{
    // TODO: Add your control notification handler code here
    TestClassxD Testdlg;
    Testdlg.DoModal();
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
void CTreadTestDlg::TestFunktion()
{
int Test = m_iAdrBits;
m_iAdrBits++;
}

void CTreadTestDlg::OnButtonstartdlg()
{
// TODO: Add your control notification handler code here
TestClassxD Testdlg;
Testdlg.DoModal();
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
void CTreadTestDlg::TestFunktion()
{
    int Test = m_iAdrBits;
    m_iAdrBits++;
}

void CTreadTestDlg::OnButtonstartdlg()
{
    // TODO: Add your control notification handler code here
    TestClassxD Testdlg;
    Testdlg.DoModal();
}


Diese Klasse beinhaltet die Memberfunktion Testfunktion(), in welcher auf die Membervariable m_iAdrBits zugegriffen wird.
Mit Klick auf den Button StartDlg wird ein ChildDialog erstellt, in welchem folgendes passiert:

.h file:
C/C++ Code:
1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
    static UINT StartThread (LPVOID param);    //controlling function header
   
    typedef struct THREADSTRUCT                //structure for passing to the controlling function
    {
        TestClassxD*    _this;   //this Objekt auf die Child Klasse
        CTreadTestDlg*    ParentThread;  //Objekt des ersten Dialogs

    } THREADSTRUCT;
C/C++ Code:
1
2
3
4
5
6
7
8
static UINT StartThread (LPVOID param); //controlling function header

typedef struct THREADSTRUCT //structure for passing to the controlling function
{
TestClassxD* _this; //this Objekt auf die Child Klasse
CTreadTestDlg* ParentThread; //Objekt des ersten Dialogs

} THREADSTRUCT;
C/C++ Code:
1
2
3
4
5
6
7
8
    static UINT StartThread (LPVOID param);    //controlling function header
   
    typedef struct THREADSTRUCT                //structure for passing to the controlling function
    {
        TestClassxD*    _this;   //this Objekt auf die Child Klasse
        CTreadTestDlg*    ParentThread;  //Objekt des ersten Dialogs

    } THREADSTRUCT;


.cpp file:
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
void TestClassxD::OnButtonstart()
{
    cancelflag = 0;
    UpdateData(TRUE);
    THREADSTRUCT *_param = new THREADSTRUCT;
    _param->_this = this;
    AfxBeginThread (StartThread, _param);
}

void TestClassxD::OnButtonstop()
{
    // TODO: Add your control notification handler code here
    cancelflag = 1;
}

UINT TestClassxD::StartThread (LPVOID param)
{
    THREADSTRUCT*    ts = (THREADSTRUCT*)param;
   
    //here is the time-consuming process which interacts with your dialog
    AfxMessageBox ("Thread is started!");
   
    ts->_this->m_progressBar.SetRange (0, 1000);

    for (int i=0; i<(ts->_this->m_iCycles); i++)
    {
        if(!(ts->_this->cancelflag == 1))
        {
            Sleep(5);
            ts->_this->m_progressBar.SetPos(i+1);
            ts->ParentThread->TestFunktion();           
        }
    }

    //you can also call AfxEndThread() here
    return 1;
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
void TestClassxD::OnButtonstart()
{
cancelflag = 0;
UpdateData(TRUE);
THREADSTRUCT *_param = new THREADSTRUCT;
_param->_this = this;
AfxBeginThread (StartThread, _param);
}

void TestClassxD::OnButtonstop()
{
// TODO: Add your control notification handler code here
cancelflag = 1;
}

UINT TestClassxD::StartThread (LPVOID param)
{
THREADSTRUCT* ts = (THREADSTRUCT*)param;

//here is the time-consuming process which interacts with your dialog
AfxMessageBox ("Thread is started!");

ts->_this->m_progressBar.SetRange (0, 1000);

for (int i=0; i<(ts->_this->m_iCycles); i++)
{
if(!(ts->_this->cancelflag == 1))
{
Sleep(5);
ts->_this->m_progressBar.SetPos(i+1);
ts->ParentThread->TestFunktion();
}
}

//you can also call AfxEndThread() here
return 1;
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
void TestClassxD::OnButtonstart()
{
    cancelflag = 0;
    UpdateData(TRUE);
    THREADSTRUCT *_param = new THREADSTRUCT;
    _param->_this = this;
    AfxBeginThread (StartThread, _param);
}

void TestClassxD::OnButtonstop()
{
    // TODO: Add your control notification handler code here
    cancelflag = 1;
}

UINT TestClassxD::StartThread (LPVOID param)
{
    THREADSTRUCT*    ts = (THREADSTRUCT*)param;
   
    //here is the time-consuming process which interacts with your dialog
    AfxMessageBox ("Thread is started!");
   
    ts->_this->m_progressBar.SetRange (0, 1000);

    for (int i=0; i<(ts->_this->m_iCycles); i++)
    {
        if(!(ts->_this->cancelflag == 1))
        {
            Sleep(5);
            ts->_this->m_progressBar.SetPos(i+1);
            ts->ParentThread->TestFunktion();           
        }
    }

    //you can also call AfxEndThread() here
    return 1;
}


Und natürlich ist der Fehler immernoch vorhanden, dass wenn ich die Testfunktion des ersten Dialogs aufrufe, ein Access Violation Fehler kommt, weil er den Inhalt von m_iAdrBits nicht kennt...obwohl m_iAdrBits im OnInitDialog() des ersten Dialogs initialisiert und einen Wert erhalten hat.

Ist das was ich will überhaupt möglich? Oder versteht nur niemand was ich möchte? ;)

PS: Das ist jetzt nur ein kleines Beispielprogramm, was ich in meine komplexere Anwendung integrieren muss/möchte... :warning:

PS2@Mods: Vielleicht wär es möglich den Titel zu ändern? Ich möchte nur kein neues Thema eröffnen, da es ja alles zusammen hängt...
Titelvorschlag: "aus Workerthread auf Membervariablen eines anderen Dialogs zugreifen" ...wenn das sachlich richtig ist ;)


Zuletzt bearbeitet von KPY3EP am 12:29:37 02.02.2012, insgesamt 1-mal bearbeitet
hustbaer
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.10.2006
Beiträge: 13529
Beitrag hustbaer Mitglied 13:35:13 02.02.2012   Titel:              Zitieren

Du initialisierst in deinem Beispiel THREADSTRUCT::ParentThread nirgends, greifst aber in der Thread-Funktion darauf zu (ts->ParentThread->...).
Ich würde sagen poste mal 1:1 Code aus einem "funktionierenden" Beispiel, mit dem du das Problem nachstellen kannst.

Code den man schnell für's Posten im Forum zurechtschnippelt oder gar "nachtippt" (ohne ihn ausprobiert zu haben) ist in solchen Fällen selten hilfreich.

Und natürlich darfst du nur aus dem Thread auf ein Fenster bzw. einen Dialog zugreifen, der dieses Fenster/diesen Dialog auch erzeugt hat.
D.h. du darfst aus dem Thread nicht auf ts->_this->m_progressBar zugreifen.

Was OK wäre, wäre mit die entsprechende Message mit PostMessage() abzusetzen.

_________________
"Let there be Licht..." http://lichttools.sourceforge.net/
Sehr cooles ASCII Spiel (leider nicht von mir): ASCII-Scramble - http://www.roskakori.at/ascii/
KPY3EP
Mitglied

Benutzerprofil
Anmeldungsdatum: 01.02.2012
Beiträge: 3
Beitrag KPY3EP Mitglied 13:48:24 02.02.2012   Titel:              Zitieren

Hmm...danke, aber irgendwie kritisierst du immer das, was funktioniert ;)

Zitat:
D.h. du darfst aus dem Thread nicht auf ts->_this->m_progressBar zugreifen


Warum?! Es funktioniert einwandfrei!

Zitat:
Du initialisierst in deinem Beispiel THREADSTRUCT::ParentThread nirgends, greifst aber in der Thread-Funktion darauf zu (ts->ParentThread->...).


C/C++ Code:
    typedef struct THREADSTRUCT                //structure for passing to the controlling function
    {
        TestClassxD*    _this;   //this Objekt auf die Child Klasse
        CTreadTestDlg*    ParentThread;  //Objekt des ersten Dialogs

    } THREADSTRUCT
C/C++ Code:
typedef struct THREADSTRUCT //structure for passing to the controlling function
{
TestClassxD* _this; //this Objekt auf die Child Klasse
CTreadTestDlg* ParentThread; //Objekt des ersten Dialogs

} THREADSTRUCT
C/C++ Code:
    typedef struct THREADSTRUCT                //structure for passing to the controlling function
    {
        TestClassxD*    _this;   //this Objekt auf die Child Klasse
        CTreadTestDlg*    ParentThread;  //Objekt des ersten Dialogs

    } THREADSTRUCT


soviel dazu...

Zitat:
Und natürlich darfst du nur aus dem Thread auf ein Fenster bzw. einen Dialog zugreifen, der dieses Fenster/diesen Dialog auch erzeugt hat.


OK! Zumindest hast du das Problem vor dem ich stehe erkannt. Ich versuche ja auch nicht auf Fenster/Controls/Dialog zuzugreifen, sondern auf eine Membervariable der Dialogklasse.

Ich möchte eigentlich nur wissen, ob das wirklich so ein Ding der unmöglichkeit ist. Der Luxus einen weiteren Dialog zu öffnen in welchem man einen Langzeittest starten kann ist einfang sehr Angenehm. Wenn mir aber keine Lösung einfällt/präsentiert wird, werde ich wohl die wenigen Controls aus dem Child-Dialog in den "großen" Parent Dialog implementieren, und diese per Menü einfach Disablen/Enablen...

Nicht Schön, aber wird sich im zuge von Multithreading wohl nicht ändern lassen oder? :D

Was mich aber immernoch Interessiert, ist Martin Richters vorschlag zur neutralen Struktur :confused:
wtf is das? Wie kann ich mir so etwas vorstellen? Kein Plan wie man so etwas angeht. :o)
hustbaer
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.10.2006
Beiträge: 13529
Beitrag hustbaer Mitglied 16:58:02 02.02.2012   Titel:              Zitieren

Alter Freund der schwedischen Blasmusik, ...

KPY3EP schrieb:
Hmm...danke, aber irgendwie kritisierst du immer das, was funktioniert ;)

Blubb
Zitat:

Zitat:
D.h. du darfst aus dem Thread nicht auf ts->_this->m_progressBar zugreifen


Warum?! Es funktioniert einwandfrei!

Weil m_progressBar ein CONTROL aka. FENSTER ist. Das darfst du nur aus dem Thread verwenden der es erzeugt hat. OK, unter bestimmten Voraussetzungen funktioniert das auch "gut" über Thread-Grenzen hinweg, man kann sich aber ganz leicht damit rückwärts durchs Knie schiessen.

Zitat:

Zitat:
Du initialisierst in deinem Beispiel THREADSTRUCT::ParentThread nirgends, greifst aber in der Thread-Funktion darauf zu (ts->ParentThread->...).


C/C++ Code:
    typedef struct THREADSTRUCT                //structure for passing to the controlling function
    {
        TestClassxD*    _this;   //this Objekt auf die Child Klasse
        CTreadTestDlg*    ParentThread;  //Objekt des ersten Dialogs

    } THREADSTRUCT
C/C++ Code:
typedef struct THREADSTRUCT //structure for passing to the controlling function
{
TestClassxD* _this; //this Objekt auf die Child Klasse
CTreadTestDlg* ParentThread; //Objekt des ersten Dialogs

} THREADSTRUCT
C/C++ Code:
    typedef struct THREADSTRUCT                //structure for passing to the controlling function
    {
        TestClassxD*    _this;   //this Objekt auf die Child Klasse
        CTreadTestDlg*    ParentThread;  //Objekt des ersten Dialogs

    } THREADSTRUCT


soviel dazu...

Ist dir die Bedeutung des Wortes "initialisieren" bekannt?
Ja? Glaub ich nicht
C/C++ Code:
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
void TestClassxD::OnButtonstart()
{
    cancelflag = 0;
    UpdateData(TRUE);
    THREADSTRUCT *_param = new THREADSTRUCT;
    _param->_this = this;
    // HIER FEHLT EIN _param->ParentThread = irgendwas;
    AfxBeginThread (StartThread, _param);
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
void TestClassxD::OnButtonstart()
{
cancelflag = 0;
UpdateData(TRUE);
THREADSTRUCT *_param = new THREADSTRUCT;
_param->_this = this;
// HIER FEHLT EIN _param->ParentThread = irgendwas;
AfxBeginThread (StartThread, _param);
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
void TestClassxD::OnButtonstart()
{
    cancelflag = 0;
    UpdateData(TRUE);
    THREADSTRUCT *_param = new THREADSTRUCT;
    _param->_this = this;
    // HIER FEHLT EIN _param->ParentThread = irgendwas;
    AfxBeginThread (StartThread, _param);
}

Soviel dazu.

_________________
"Let there be Licht..." http://lichttools.sourceforge.net/
Sehr cooles ASCII Spiel (leider nicht von mir): ASCII-Scramble - http://www.roskakori.at/ascii/
KPY3EP
Mitglied

Benutzerprofil
Anmeldungsdatum: 01.02.2012
Beiträge: 3
Beitrag KPY3EP Mitglied 10:51:39 03.02.2012   Titel:              Zitieren

Ich glaub du verstehst imemr noch nicht, was ich will...lies dir bitte nochmal meinen Letzten Post unterster Absatz durch.

Zitat:
Weil m_progressBar ein CONTROL aka. FENSTER ist. Das darfst du nur aus dem Thread verwenden der es erzeugt hat. OK, unter bestimmten Voraussetzungen funktioniert das auch "gut" über Thread-Grenzen hinweg, man kann sich aber ganz leicht damit rückwärts durchs Knie schiessen.


Was ne Begründung...
Und warum machen das alle so? Selbst in dem Beispiel welches hier verlinkt wurde wird es so gemacht. :rolleyes:

Zitat:
OK! Zumindest hast du das Problem vor dem ich stehe erkannt.

Diese Aussage nehme ich zurück. Ich versuch nochmals zu erklären worum es geht.

vielleicht hilft ASCII-Art :D
Code:
____________________       ______________________
|     Dialog       |       |      Dialog        |     ___________________
|       1          |   =>  |         2          | =>  |   Workerthread  |---.
--------------------       ----------------------     -------------------   |
        ^                             ^                                     |
        |                             |                                     |
        ---------------------------------------------------------------------
Code:
____________________ ______________________
| Dialog | | Dialog | ___________________
| 1 | => | 2 | => | Workerthread |---.
-------------------- ---------------------- ------------------- |
^ ^ |
| | |
---------------------------------------------------------------------
Code:
____________________       ______________________
|     Dialog       |       |      Dialog        |     ___________________
|       1          |   =>  |         2          | =>  |   Workerthread  |---.
--------------------       ----------------------     -------------------   |
        ^                             ^                                     |
        |                             |                                     |
        ---------------------------------------------------------------------

zugriff vom Workerthread auf Membervariablen /Methoden der Dialogklassen...

Das funktioniert bisher nur für Dialog 2. beim Zugriff auf Dialog 1 kommt Error.

Ich bin zwar sowieso schon damit fertig, und hab es anders gelöst, jedoch interessiert mich ob bzw. was hier die schwierigkeit darstellt...


Zuletzt bearbeitet von KPY3EP am 10:52:28 03.02.2012, insgesamt 1-mal bearbeitet
hustbaer
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.10.2006
Beiträge: 13529
Beitrag hustbaer Mitglied 12:47:18 03.02.2012   Titel:              Zitieren

Also ganz langsam zum mitschreiben.

Du hast da eine Zeile
C/C++ Code:
ts->ParentThread->TestFunktion();
C/C++ Code:
ts->ParentThread->TestFunktion();
C/C++ Code:
ts->ParentThread->TestFunktion();

in deinem Programm.
ts ist die "THREADSTRUCT" die du mit folgender Funktion zusammenbaust
C/C++ Code:
1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
void TestClassxD::OnButtonstart()
{
    cancelflag = 0;
    UpdateData(TRUE);
    THREADSTRUCT *_param = new THREADSTRUCT;
    _param->_this = this;
    AfxBeginThread (StartThread, _param);
}
C/C++ Code:
1
2
3
4
5
6
7
8
void TestClassxD::OnButtonstart()
{
cancelflag = 0;
UpdateData(TRUE);
THREADSTRUCT *_param = new THREADSTRUCT;
_param->_this = this;
AfxBeginThread (StartThread, _param);
}
C/C++ Code:
1
2
3
4
5
6
7
8
void TestClassxD::OnButtonstart()
{
    cancelflag = 0;
    UpdateData(TRUE);
    THREADSTRUCT *_param = new THREADSTRUCT;
    _param->_this = this;
    AfxBeginThread (StartThread, _param);
}

Da wird die Membervariable "ParentThread" bloss leider nie geschrieben. D.h. da steht ne Hausnummer drin.
D.h. du greifst nicht auf den "Dialog 1" zu, sondern einfach irgendwo in den Speicher. Und deswegen schnalzt es dort.

Wenn du nicht unglaublich schwer von Begriff bist, müsstest du das eigentlich verstehen.


KPY3EP schrieb:
Ich glaub du verstehst imemr noch nicht, was ich will...lies dir bitte nochmal meinen Letzten Post unterster Absatz durch.

Und ich glaube du hast einfach keine Ahnung von Programmieren.

Zitat:
Zitat:
Weil m_progressBar ein CONTROL aka. FENSTER ist. Das darfst du nur aus dem Thread verwenden der es erzeugt hat. OK, unter bestimmten Voraussetzungen funktioniert das auch "gut" über Thread-Grenzen hinweg, man kann sich aber ganz leicht damit rückwärts durchs Knie schiessen.


Was ne Begründung...
Und warum machen das alle so? Selbst in dem Beispiel welches hier verlinkt wurde wird es so gemacht. :rolleyes:

Was kann ich dafür dass Heerscharen von Programmierern keinen Tau von Multithreading haben?
Das m_progressBar.SetPos() ist für sich genommen noch kein Problem.
Problematisch wird es meistens dann, wenn die Leute versuchen den Thread im OnOK/OnClose des "parent" Dialogs zu beenden.

Zitat:
Ich bin zwar sowieso schon damit fertig, und hab es anders gelöst, jedoch interessiert mich ob bzw. was hier die schwierigkeit darstellt...

Dann solltest du vielleicht lesen was ich dir schreiben, anstatt immer nur zu behaupten dass ich dein Problem nicht verstanden habe.
So ein Dialog der nen Worker-Thread rausstartet ist genau überhaupt kein Problem, das hat man in ein paar Minuten runterprogrammiert.

_________________
"Let there be Licht..." http://lichttools.sourceforge.net/
Sehr cooles ASCII Spiel (leider nicht von mir): ASCII-Scramble - http://www.roskakori.at/ascii/
C/C++ Forum :: MFC (Visual C++) ::  MFC Dialog im laufenden Prozess beenden OHNE Multithreading   Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info, www.c-sar.de, www.c-plusplus.net und www.baeckmann.de enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.