Bonjour,
Voici mon problème:
j'ai une boite de dialogue qui, lorsque l'on click sur un bouton ouvre
une autre boite de dialogue (modal avec DoModal())qui contient une
Progress Bar. dans la fonction OnInitDialog() je lance un thread:
AfxBeginThread(mafunc, this);
avec mafunc qui s'occupe d'effectuer quelque calcul et mettre à jour
la Progress Bar. dans la fonction mafunc, j'ai une boucle for qui
boucle un certain nombre de fois mais on doit sortir de la boucle
quand on appuie sur le bouton cancel en dessous de la Progress Bar.
Voici le principe:
voila le problème est que ca marche une fois sur 6. et de temps en
temps, quand j'appuie sur le bouton cancel, j'ai un access violation
wincore.cpp ligne 980 user32.dll
bref, est-ce que ma facon est bonne, sinon comment faire?
merci d'avance.
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
AG
maxime wrote:
Bonjour, Voici mon problème: j'ai une boite de dialogue qui, lorsque l'on click sur un bouton ouvre une autre boite de dialogue (modal avec DoModal())
Donc si j'ai bien compris, la fonction maclasse::OnCancel() est appelée par le thread original. Alors que c'est le second thread (le thread de calcul) qui fait la boucle for dans lequel la variable 'var' est utilisée comme critère d'arret.
Si ton architecture correspond à ce que j'ai énnoncé plus haut, il y a déjà un problème : Deux thread accèdent à la même variable de manière concurente. C'est source de problèmes car les opérations de lecture et d'écriture ne sont pas atomiques.
Solution : il existe plusieurs solutions pour ce genre de problème. Il s'agit de faire communiquer deux thread l'un avec l'autre.
Tu peux utiliser les messages (poster un message dans la pompe du thread de calcul lui indiquant que quelqu'un à pressé sur Cancel). C'est peut être un peu lourd. Tu peux utiliser un event, c'est beaucoup moins lourd, et c'est généralement ce qu'on fait (http://groups.google.fr/groups?hl=fr&lr=&ie=UTF-8&threadm>477B5A.3080808%40tb.fr&rnum=1&prev=/groups%3Fq%3Dworker%2Bevent%2Bthread%2Bfr.comp.os%2Balexandre%26hl%3Dfr%26lr%3D%26ie%3DUTF-8%26selm%3D3E477B5A.3080808%2540tb.fr%26rnum%3D1)
Tu peux utiliser les points de synchronisation classiques (mutex, sémaphore), mais j'ai jamais fait.
Alexandre.
maxime wrote:
Bonjour,
Voici mon problème:
j'ai une boite de dialogue qui, lorsque l'on click sur un bouton ouvre
une autre boite de dialogue (modal avec DoModal())
Donc si j'ai bien compris, la fonction maclasse::OnCancel() est appelée
par le thread original. Alors que c'est le second thread (le thread de
calcul) qui fait la boucle for dans lequel la variable 'var' est
utilisée comme critère d'arret.
Si ton architecture correspond à ce que j'ai énnoncé plus haut, il y a
déjà un problème : Deux thread accèdent à la même variable de manière
concurente. C'est source de problèmes car les opérations de lecture et
d'écriture ne sont pas atomiques.
Solution : il existe plusieurs solutions pour ce genre de problème. Il
s'agit de faire communiquer deux thread l'un avec l'autre.
Tu peux utiliser les messages (poster un message dans la pompe du thread
de calcul lui indiquant que quelqu'un à pressé sur Cancel). C'est peut
être un peu lourd.
Tu peux utiliser un event, c'est beaucoup moins lourd, et c'est
généralement ce qu'on fait
(http://groups.google.fr/groups?hl=fr&lr=&ie=UTF-8&threadm>477B5A.3080808%40tb.fr&rnum=1&prev=/groups%3Fq%3Dworker%2Bevent%2Bthread%2Bfr.comp.os%2Balexandre%26hl%3Dfr%26lr%3D%26ie%3DUTF-8%26selm%3D3E477B5A.3080808%2540tb.fr%26rnum%3D1)
Tu peux utiliser les points de synchronisation classiques (mutex,
sémaphore), mais j'ai jamais fait.
Bonjour, Voici mon problème: j'ai une boite de dialogue qui, lorsque l'on click sur un bouton ouvre une autre boite de dialogue (modal avec DoModal())
Donc si j'ai bien compris, la fonction maclasse::OnCancel() est appelée par le thread original. Alors que c'est le second thread (le thread de calcul) qui fait la boucle for dans lequel la variable 'var' est utilisée comme critère d'arret.
Si ton architecture correspond à ce que j'ai énnoncé plus haut, il y a déjà un problème : Deux thread accèdent à la même variable de manière concurente. C'est source de problèmes car les opérations de lecture et d'écriture ne sont pas atomiques.
Solution : il existe plusieurs solutions pour ce genre de problème. Il s'agit de faire communiquer deux thread l'un avec l'autre.
Tu peux utiliser les messages (poster un message dans la pompe du thread de calcul lui indiquant que quelqu'un à pressé sur Cancel). C'est peut être un peu lourd. Tu peux utiliser un event, c'est beaucoup moins lourd, et c'est généralement ce qu'on fait (http://groups.google.fr/groups?hl=fr&lr=&ie=UTF-8&threadm>477B5A.3080808%40tb.fr&rnum=1&prev=/groups%3Fq%3Dworker%2Bevent%2Bthread%2Bfr.comp.os%2Balexandre%26hl%3Dfr%26lr%3D%26ie%3DUTF-8%26selm%3D3E477B5A.3080808%2540tb.fr%26rnum%3D1)
Tu peux utiliser les points de synchronisation classiques (mutex, sémaphore), mais j'ai jamais fait.
Alexandre.
Drummy
Apparemment il est tout à fait possible de partager des variables entre threads, je vous invite à lire la réponse à mon post "thread over?" sur comp.os.ms-windows.programmer.win32 daté du 21/06/2004 à 13h. mais effectivement la meilleur solution (qui marche) reste de poster un custom message (ayant pour code WM_APP+n) avec PostMessage.
"AG" a écrit dans le message de news:40d1508e$0$4975$
maxime wrote:
> Bonjour, > Voici mon problème: > j'ai une boite de dialogue qui, lorsque l'on click sur un bouton ouvre > une autre boite de dialogue (modal avec DoModal())
Donc si j'ai bien compris, la fonction maclasse::OnCancel() est appelée par le thread original. Alors que c'est le second thread (le thread de calcul) qui fait la boucle for dans lequel la variable 'var' est utilisée comme critère d'arret.
Si ton architecture correspond à ce que j'ai énnoncé plus haut, il y a déjà un problème : Deux thread accèdent à la même variable de manière concurente. C'est source de problèmes car les opérations de lecture et d'écriture ne sont pas atomiques.
Solution : il existe plusieurs solutions pour ce genre de problème. Il s'agit de faire communiquer deux thread l'un avec l'autre.
Tu peux utiliser les messages (poster un message dans la pompe du thread de calcul lui indiquant que quelqu'un à pressé sur Cancel). C'est peut être un peu lourd. Tu peux utiliser un event, c'est beaucoup moins lourd, et c'est généralement ce qu'on fait
Tu peux utiliser les points de synchronisation classiques (mutex, sémaphore), mais j'ai jamais fait.
Alexandre.
Apparemment il est tout à fait possible de partager des variables entre
threads, je vous invite à lire la réponse à mon post "thread over?" sur
comp.os.ms-windows.programmer.win32 daté du 21/06/2004 à 13h.
mais effectivement la meilleur solution (qui marche) reste de poster un
custom message (ayant pour code WM_APP+n) avec PostMessage.
"AG" <ag@tb.fr> a écrit dans le message de
news:40d1508e$0$4975$626a14ce@news.free.fr...
maxime wrote:
> Bonjour,
> Voici mon problème:
> j'ai une boite de dialogue qui, lorsque l'on click sur un bouton ouvre
> une autre boite de dialogue (modal avec DoModal())
Donc si j'ai bien compris, la fonction maclasse::OnCancel() est appelée
par le thread original. Alors que c'est le second thread (le thread de
calcul) qui fait la boucle for dans lequel la variable 'var' est
utilisée comme critère d'arret.
Si ton architecture correspond à ce que j'ai énnoncé plus haut, il y a
déjà un problème : Deux thread accèdent à la même variable de manière
concurente. C'est source de problèmes car les opérations de lecture et
d'écriture ne sont pas atomiques.
Solution : il existe plusieurs solutions pour ce genre de problème. Il
s'agit de faire communiquer deux thread l'un avec l'autre.
Tu peux utiliser les messages (poster un message dans la pompe du thread
de calcul lui indiquant que quelqu'un à pressé sur Cancel). C'est peut
être un peu lourd.
Tu peux utiliser un event, c'est beaucoup moins lourd, et c'est
généralement ce qu'on fait
Apparemment il est tout à fait possible de partager des variables entre threads, je vous invite à lire la réponse à mon post "thread over?" sur comp.os.ms-windows.programmer.win32 daté du 21/06/2004 à 13h. mais effectivement la meilleur solution (qui marche) reste de poster un custom message (ayant pour code WM_APP+n) avec PostMessage.
"AG" a écrit dans le message de news:40d1508e$0$4975$
maxime wrote:
> Bonjour, > Voici mon problème: > j'ai une boite de dialogue qui, lorsque l'on click sur un bouton ouvre > une autre boite de dialogue (modal avec DoModal())
Donc si j'ai bien compris, la fonction maclasse::OnCancel() est appelée par le thread original. Alors que c'est le second thread (le thread de calcul) qui fait la boucle for dans lequel la variable 'var' est utilisée comme critère d'arret.
Si ton architecture correspond à ce que j'ai énnoncé plus haut, il y a déjà un problème : Deux thread accèdent à la même variable de manière concurente. C'est source de problèmes car les opérations de lecture et d'écriture ne sont pas atomiques.
Solution : il existe plusieurs solutions pour ce genre de problème. Il s'agit de faire communiquer deux thread l'un avec l'autre.
Tu peux utiliser les messages (poster un message dans la pompe du thread de calcul lui indiquant que quelqu'un à pressé sur Cancel). C'est peut être un peu lourd. Tu peux utiliser un event, c'est beaucoup moins lourd, et c'est généralement ce qu'on fait
Tu peux utiliser les points de synchronisation classiques (mutex, sémaphore), mais j'ai jamais fait.
Alexandre.
AG
Drummy wrote:
Apparemment il est tout à fait possible de partager des variables entre threads, je vous invite à lire la réponse à mon post "thread over?" sur comp.os.ms-windows.programmer.win32 daté du 21/06/2004 à 13h. mais effectivement la meilleur solution (qui marche) reste de poster un custom message (ayant pour code WM_APP+n) avec PostMessage.
J'ai bien peur que tu ais mal compris mon poste. Lorsqu'on partage des variables, on utilise des méchanismes de synchronisations qui évitent à deux thread de faire une lecture ou une écriture en même temps. Ces mécanismes de synchronisation sont mis en oeuvre par l'intermédiaires d'objets que sont les mutex ou les sémaphores. Tu seras surement intéressé par les pages suivantes :
Autrement dis, je n'ai jamais dis qu'il n'était pas possible de partager des variables entre thread, j'ai dit que ce n'etait pas possible de le faire sans utiliser ces points de synchronisation.
AG
Drummy wrote:
Apparemment il est tout à fait possible de partager des variables entre
threads, je vous invite à lire la réponse à mon post "thread over?" sur
comp.os.ms-windows.programmer.win32 daté du 21/06/2004 à 13h.
mais effectivement la meilleur solution (qui marche) reste de poster un
custom message (ayant pour code WM_APP+n) avec PostMessage.
J'ai bien peur que tu ais mal compris mon poste. Lorsqu'on partage des
variables, on utilise des méchanismes de synchronisations qui évitent à
deux thread de faire une lecture ou une écriture en même temps. Ces
mécanismes de synchronisation sont mis en oeuvre par l'intermédiaires
d'objets que sont les mutex ou les sémaphores. Tu seras surement
intéressé par les pages suivantes :
Autrement dis, je n'ai jamais dis qu'il n'était pas possible de partager
des variables entre thread, j'ai dit que ce n'etait pas possible de le
faire sans utiliser ces points de synchronisation.
Apparemment il est tout à fait possible de partager des variables entre threads, je vous invite à lire la réponse à mon post "thread over?" sur comp.os.ms-windows.programmer.win32 daté du 21/06/2004 à 13h. mais effectivement la meilleur solution (qui marche) reste de poster un custom message (ayant pour code WM_APP+n) avec PostMessage.
J'ai bien peur que tu ais mal compris mon poste. Lorsqu'on partage des variables, on utilise des méchanismes de synchronisations qui évitent à deux thread de faire une lecture ou une écriture en même temps. Ces mécanismes de synchronisation sont mis en oeuvre par l'intermédiaires d'objets que sont les mutex ou les sémaphores. Tu seras surement intéressé par les pages suivantes :
Autrement dis, je n'ai jamais dis qu'il n'était pas possible de partager des variables entre thread, j'ai dit que ce n'etait pas possible de le faire sans utiliser ces points de synchronisation.
AG
Patrick Philippot
maxime wrote:
Bonjour, Voici mon problème: j'ai une boite de dialogue qui, lorsque l'on click sur un bouton ouvre une autre boite de dialogue (modal avec DoModal())qui contient une Progress Bar. dans la fonction OnInitDialog() je lance un thread:
Bonjour,
Je crois que vous êtes tombé dans un piège classique des MFC. On ne peut pas utiliser dans un thread un pointeur vers une classe dérivée de CWnd si l'instance de cette classe a été créée dans un autre thread. Cela est dû à la manière dont les MFC stockent les maps qui font la correspondance entre le handle de la fenêtre et le pointeur vers l'instance de la classe qui représente la fenêtre. La plupart du temps, ces maps sont locales au thread créateur. Ce qui veut dire en clair qu'un pointeur vers une class CWnd ou dérivée instanciée dans un thread ne peut pas être passé à un autre thread. Si je lis bien votre code, c'est ce que vous faites.
Ce qu'il faut faire c'est passer le handle de la fenêtre à l'autre thread, recréer une instance de la classe locale au thread destinataire (cette instanciation peut se faire grâce à la méthode CWnd::FromHandlePermanent) et utiliser cette instance pour manipuler la fenêtre. Il y a aura donc à ce moment, 2 instances de CWnd ou dérivée pointant sur la même fenêtre, une dans chaque thread.
Quand vous n'avez plus besoin de l'instance de CWnd créée dans le thread secondaire, utilisez Detach avant que l'objet ne soit détruit pour éviter la destruction de la fenêtre.
-- Patrick Philippot - Microsoft MVP [.Net] MainSoft Consulting Services www.mainsoft.fr
maxime wrote:
Bonjour,
Voici mon problème:
j'ai une boite de dialogue qui, lorsque l'on click sur un bouton ouvre
une autre boite de dialogue (modal avec DoModal())qui contient une
Progress Bar. dans la fonction OnInitDialog() je lance un thread:
Bonjour,
Je crois que vous êtes tombé dans un piège classique des MFC. On ne peut
pas utiliser dans un thread un pointeur vers une classe dérivée de CWnd
si l'instance de cette classe a été créée dans un autre thread. Cela est
dû à la manière dont les MFC stockent les maps qui font la
correspondance entre le handle de la fenêtre et le pointeur vers
l'instance de la classe qui représente la fenêtre. La plupart du temps,
ces maps sont locales au thread créateur. Ce qui veut dire en clair
qu'un pointeur vers une class CWnd ou dérivée instanciée dans un thread
ne peut pas être passé à un autre thread. Si je lis bien votre code,
c'est ce que vous faites.
Ce qu'il faut faire c'est passer le handle de la fenêtre à l'autre
thread, recréer une instance de la classe locale au thread destinataire
(cette instanciation peut se faire grâce à la méthode
CWnd::FromHandlePermanent) et utiliser cette instance pour manipuler la
fenêtre. Il y a aura donc à ce moment, 2 instances de CWnd ou dérivée
pointant sur la même fenêtre, une dans chaque thread.
Quand vous n'avez plus besoin de l'instance de CWnd créée dans le thread
secondaire, utilisez Detach avant que l'objet ne soit détruit pour
éviter la destruction de la fenêtre.
--
Patrick Philippot - Microsoft MVP [.Net]
MainSoft Consulting Services
www.mainsoft.fr
Bonjour, Voici mon problème: j'ai une boite de dialogue qui, lorsque l'on click sur un bouton ouvre une autre boite de dialogue (modal avec DoModal())qui contient une Progress Bar. dans la fonction OnInitDialog() je lance un thread:
Bonjour,
Je crois que vous êtes tombé dans un piège classique des MFC. On ne peut pas utiliser dans un thread un pointeur vers une classe dérivée de CWnd si l'instance de cette classe a été créée dans un autre thread. Cela est dû à la manière dont les MFC stockent les maps qui font la correspondance entre le handle de la fenêtre et le pointeur vers l'instance de la classe qui représente la fenêtre. La plupart du temps, ces maps sont locales au thread créateur. Ce qui veut dire en clair qu'un pointeur vers une class CWnd ou dérivée instanciée dans un thread ne peut pas être passé à un autre thread. Si je lis bien votre code, c'est ce que vous faites.
Ce qu'il faut faire c'est passer le handle de la fenêtre à l'autre thread, recréer une instance de la classe locale au thread destinataire (cette instanciation peut se faire grâce à la méthode CWnd::FromHandlePermanent) et utiliser cette instance pour manipuler la fenêtre. Il y a aura donc à ce moment, 2 instances de CWnd ou dérivée pointant sur la même fenêtre, une dans chaque thread.
Quand vous n'avez plus besoin de l'instance de CWnd créée dans le thread secondaire, utilisez Detach avant que l'objet ne soit détruit pour éviter la destruction de la fenêtre.
-- Patrick Philippot - Microsoft MVP [.Net] MainSoft Consulting Services www.mainsoft.fr
Patrice Labracherie
salut
comme dit plus bas, faut pas utiliser dasn un thread des objets gdi créés dans un autre. moi perso j'utilise un timer(wm_timer) en + ie: le thread alimente une variable le timer prend le résultat de la variable et modifie le controle en conséquent (dans ton cas, la progressbar)
"maxime" a écrit dans le message news:
Bonjour, Voici mon problème: j'ai une boite de dialogue qui, lorsque l'on click sur un bouton ouvre une autre boite de dialogue (modal avec DoModal())qui contient une Progress Bar. dans la fonction OnInitDialog() je lance un thread:
AfxBeginThread(mafunc, this);
avec mafunc qui s'occupe d'effectuer quelque calcul et mettre à jour la Progress Bar. dans la fonction mafunc, j'ai une boucle for qui boucle un certain nombre de fois mais on doit sortir de la boucle quand on appuie sur le bouton cancel en dessous de la Progress Bar. Voici le principe:
voila le problème est que ca marche une fois sur 6. et de temps en temps, quand j'appuie sur le bouton cancel, j'ai un access violation wincore.cpp ligne 980 user32.dll
bref, est-ce que ma facon est bonne, sinon comment faire? merci d'avance.
salut
comme dit plus bas, faut pas utiliser dasn un thread des objets gdi créés
dans un autre.
moi perso j'utilise un timer(wm_timer) en +
ie:
le thread alimente une variable
le timer prend le résultat de la variable et modifie le controle en
conséquent (dans ton cas, la progressbar)
"maxime" <maxime_phan@hotmail.com> a écrit dans le message news:
4cc9a89e.0406162253.8058204@posting.google.com...
Bonjour,
Voici mon problème:
j'ai une boite de dialogue qui, lorsque l'on click sur un bouton ouvre
une autre boite de dialogue (modal avec DoModal())qui contient une
Progress Bar. dans la fonction OnInitDialog() je lance un thread:
AfxBeginThread(mafunc, this);
avec mafunc qui s'occupe d'effectuer quelque calcul et mettre à jour
la Progress Bar. dans la fonction mafunc, j'ai une boucle for qui
boucle un certain nombre de fois mais on doit sortir de la boucle
quand on appuie sur le bouton cancel en dessous de la Progress Bar.
Voici le principe:
voila le problème est que ca marche une fois sur 6. et de temps en
temps, quand j'appuie sur le bouton cancel, j'ai un access violation
wincore.cpp ligne 980 user32.dll
bref, est-ce que ma facon est bonne, sinon comment faire?
merci d'avance.
comme dit plus bas, faut pas utiliser dasn un thread des objets gdi créés dans un autre. moi perso j'utilise un timer(wm_timer) en + ie: le thread alimente une variable le timer prend le résultat de la variable et modifie le controle en conséquent (dans ton cas, la progressbar)
"maxime" a écrit dans le message news:
Bonjour, Voici mon problème: j'ai une boite de dialogue qui, lorsque l'on click sur un bouton ouvre une autre boite de dialogue (modal avec DoModal())qui contient une Progress Bar. dans la fonction OnInitDialog() je lance un thread:
AfxBeginThread(mafunc, this);
avec mafunc qui s'occupe d'effectuer quelque calcul et mettre à jour la Progress Bar. dans la fonction mafunc, j'ai une boucle for qui boucle un certain nombre de fois mais on doit sortir de la boucle quand on appuie sur le bouton cancel en dessous de la Progress Bar. Voici le principe:
voila le problème est que ca marche une fois sur 6. et de temps en temps, quand j'appuie sur le bouton cancel, j'ai un access violation wincore.cpp ligne 980 user32.dll
bref, est-ce que ma facon est bonne, sinon comment faire? merci d'avance.