pourquoi pas:void* POSIXThread::threadFunction(void* ref){
Runnable* runnable = static_cast<Runnable*>(ref);
runnable->run();
delete runnable
return NULL;
}
Pour commencer, parce que tu ne peux pas passer l'adresse d'une
fonction membre à pthread_create:-).
Plus généralement, ceci suppose que le runnable est toujours
alloué dynamiquement.
Et qu'il ne contient pas de données qu'on veut propager vers
vers le thread appelant (suite à un join).
Et qu'on se contente d'ignore les exceptions. («Sweep them under
the rug », dirait-on en anglais. Je ne connais pas d'équivalent
aussi imagé en français.)
purger proprement des threads à durée de vie courte ne me
parait pas tordu ?!
Il marche pour un cas de figure bien précis.
pourquoi pas:
void* POSIXThread::threadFunction(void* ref){
Runnable* runnable = static_cast<Runnable*>(ref);
runnable->run();
delete runnable
return NULL;
}
Pour commencer, parce que tu ne peux pas passer l'adresse d'une
fonction membre à pthread_create:-).
Plus généralement, ceci suppose que le runnable est toujours
alloué dynamiquement.
Et qu'il ne contient pas de données qu'on veut propager vers
vers le thread appelant (suite à un join).
Et qu'on se contente d'ignore les exceptions. («Sweep them under
the rug », dirait-on en anglais. Je ne connais pas d'équivalent
aussi imagé en français.)
purger proprement des threads à durée de vie courte ne me
parait pas tordu ?!
Il marche pour un cas de figure bien précis.
pourquoi pas:void* POSIXThread::threadFunction(void* ref){
Runnable* runnable = static_cast<Runnable*>(ref);
runnable->run();
delete runnable
return NULL;
}
Pour commencer, parce que tu ne peux pas passer l'adresse d'une
fonction membre à pthread_create:-).
Plus généralement, ceci suppose que le runnable est toujours
alloué dynamiquement.
Et qu'il ne contient pas de données qu'on veut propager vers
vers le thread appelant (suite à un join).
Et qu'on se contente d'ignore les exceptions. («Sweep them under
the rug », dirait-on en anglais. Je ne connais pas d'équivalent
aussi imagé en français.)
purger proprement des threads à durée de vie courte ne me
parait pas tordu ?!
Il marche pour un cas de figure bien précis.
James Kanze wrote on 12/09/2008 09:44:
>> pourquoi pas:
>> void* POSIXThread::threadFunction(void* ref){
>> Runnable* runnable = static_cast<Runnable*>(ref);
>> runnable->run();
>> delete runnable
>> return NULL;
>> }
> Pour commencer, parce que tu ne peux pas passer l'adresse
> d'une fonction membre à pthread_create:-).
nous sommes d'accord!
je ne sais pas précisemment ce qu'est la définition de la
classe POSIXThread ici mais j'imaginais:
static void* POSIXThread::threadFunction(void*);
l'appelant réalisant:
Runnable* runnable = new RunnableChild(someParams);
pthread_t child = NULL;
pthread_create(&child, NULL,
POSIXThread::threadFunction, runnable);
> Plus généralement, ceci suppose que le runnable est toujours
> alloué dynamiquement.
oui, je supposais cela, je n'imagine pas qu'il ne le soit pas.
> Et qu'il ne contient pas de données qu'on veut propager vers
> vers le thread appelant (suite à un join).
de données ?... ayant une "sémantique de valeur" ? ;) le
thread peux appeler une méthode de l'appelant avec un bloc
résultat copié à la réception par cet appelant. (pratiquement
cela nécessitera un pool de réception géré par cet appelant).
> Et qu'on se contente d'ignore les exceptions. («Sweep them
> under the rug », dirait-on en anglais. Je ne connais pas
> d'équivalent aussi imagé en français.)
non pas de les ignorer, seulement de ne pas écrire sciemment
un code qui les violeraient (pthread_exit par exemple).
pour un contrôle fin, Runnable devra proposer des "suspend",
"resume", "finalize", ..., toutes asynchrones et toutes
respectueuses de la terminaison correcte du thread.
James Kanze wrote on 12/09/2008 09:44:
>> pourquoi pas:
>> void* POSIXThread::threadFunction(void* ref){
>> Runnable* runnable = static_cast<Runnable*>(ref);
>> runnable->run();
>> delete runnable
>> return NULL;
>> }
> Pour commencer, parce que tu ne peux pas passer l'adresse
> d'une fonction membre à pthread_create:-).
nous sommes d'accord!
je ne sais pas précisemment ce qu'est la définition de la
classe POSIXThread ici mais j'imaginais:
static void* POSIXThread::threadFunction(void*);
l'appelant réalisant:
Runnable* runnable = new RunnableChild(someParams);
pthread_t child = NULL;
pthread_create(&child, NULL,
POSIXThread::threadFunction, runnable);
> Plus généralement, ceci suppose que le runnable est toujours
> alloué dynamiquement.
oui, je supposais cela, je n'imagine pas qu'il ne le soit pas.
> Et qu'il ne contient pas de données qu'on veut propager vers
> vers le thread appelant (suite à un join).
de données ?... ayant une "sémantique de valeur" ? ;) le
thread peux appeler une méthode de l'appelant avec un bloc
résultat copié à la réception par cet appelant. (pratiquement
cela nécessitera un pool de réception géré par cet appelant).
> Et qu'on se contente d'ignore les exceptions. («Sweep them
> under the rug », dirait-on en anglais. Je ne connais pas
> d'équivalent aussi imagé en français.)
non pas de les ignorer, seulement de ne pas écrire sciemment
un code qui les violeraient (pthread_exit par exemple).
pour un contrôle fin, Runnable devra proposer des "suspend",
"resume", "finalize", ..., toutes asynchrones et toutes
respectueuses de la terminaison correcte du thread.
James Kanze wrote on 12/09/2008 09:44:
>> pourquoi pas:
>> void* POSIXThread::threadFunction(void* ref){
>> Runnable* runnable = static_cast<Runnable*>(ref);
>> runnable->run();
>> delete runnable
>> return NULL;
>> }
> Pour commencer, parce que tu ne peux pas passer l'adresse
> d'une fonction membre à pthread_create:-).
nous sommes d'accord!
je ne sais pas précisemment ce qu'est la définition de la
classe POSIXThread ici mais j'imaginais:
static void* POSIXThread::threadFunction(void*);
l'appelant réalisant:
Runnable* runnable = new RunnableChild(someParams);
pthread_t child = NULL;
pthread_create(&child, NULL,
POSIXThread::threadFunction, runnable);
> Plus généralement, ceci suppose que le runnable est toujours
> alloué dynamiquement.
oui, je supposais cela, je n'imagine pas qu'il ne le soit pas.
> Et qu'il ne contient pas de données qu'on veut propager vers
> vers le thread appelant (suite à un join).
de données ?... ayant une "sémantique de valeur" ? ;) le
thread peux appeler une méthode de l'appelant avec un bloc
résultat copié à la réception par cet appelant. (pratiquement
cela nécessitera un pool de réception géré par cet appelant).
> Et qu'on se contente d'ignore les exceptions. («Sweep them
> under the rug », dirait-on en anglais. Je ne connais pas
> d'équivalent aussi imagé en français.)
non pas de les ignorer, seulement de ne pas écrire sciemment
un code qui les violeraient (pthread_exit par exemple).
pour un contrôle fin, Runnable devra proposer des "suspend",
"resume", "finalize", ..., toutes asynchrones et toutes
respectueuses de la terminaison correcte du thread.
il faut que la fonction dont on passe l'adresse ait un linkage "C".
Et une fonction membre, même static, ne peut pas avoir un linkage "C".
Moi si. Dans le cas d'un thread détaché, par exemple, quelque
chose du genre de ce que fait Boost, on on copie l'objet
fonctionel, me semble très raisonable. Et dans le cas où on
utilse des threads pour la parallelisation d'un calcul, je
verrais bien quelque chose du genre :
Part2Runnable actionPart1 ;
Thread part2( &action ) ;
part2.start() ;
// execute part1 ici...
part2.join() ;
Pourquoi est-ce que je dois avoir besoin des shared_ptr ici ?
[...] on pourrait préférer utiliser join, avec un valeur de
rétour, ou des données « partagées ».
ignorer les exceptions
Ce n'est pas ça qui m'intéressait. Je me posais la question sur
leur transmission vers le thread appelant. Parfois, ça peut être
utile que l'exception se propage à travers le join, pour se
rétrouver dans le processus qui a démarrer le thread.
il faut que la fonction dont on passe l'adresse ait un linkage "C".
Et une fonction membre, même static, ne peut pas avoir un linkage "C".
Moi si. Dans le cas d'un thread détaché, par exemple, quelque
chose du genre de ce que fait Boost, on on copie l'objet
fonctionel, me semble très raisonable. Et dans le cas où on
utilse des threads pour la parallelisation d'un calcul, je
verrais bien quelque chose du genre :
Part2Runnable actionPart1 ;
Thread part2( &action ) ;
part2.start() ;
// execute part1 ici...
part2.join() ;
Pourquoi est-ce que je dois avoir besoin des shared_ptr ici ?
[...] on pourrait préférer utiliser join, avec un valeur de
rétour, ou des données « partagées ».
ignorer les exceptions
Ce n'est pas ça qui m'intéressait. Je me posais la question sur
leur transmission vers le thread appelant. Parfois, ça peut être
utile que l'exception se propage à travers le join, pour se
rétrouver dans le processus qui a démarrer le thread.
il faut que la fonction dont on passe l'adresse ait un linkage "C".
Et une fonction membre, même static, ne peut pas avoir un linkage "C".
Moi si. Dans le cas d'un thread détaché, par exemple, quelque
chose du genre de ce que fait Boost, on on copie l'objet
fonctionel, me semble très raisonable. Et dans le cas où on
utilse des threads pour la parallelisation d'un calcul, je
verrais bien quelque chose du genre :
Part2Runnable actionPart1 ;
Thread part2( &action ) ;
part2.start() ;
// execute part1 ici...
part2.join() ;
Pourquoi est-ce que je dois avoir besoin des shared_ptr ici ?
[...] on pourrait préférer utiliser join, avec un valeur de
rétour, ou des données « partagées ».
ignorer les exceptions
Ce n'est pas ça qui m'intéressait. Je me posais la question sur
leur transmission vers le thread appelant. Parfois, ça peut être
utile que l'exception se propage à travers le join, pour se
rétrouver dans le processus qui a démarrer le thread.
James Kanze wrote on 14/09/2008 11:54:
> il faut que la fonction dont on passe l'adresse ait un
> linkage "C". Et une fonction membre, même static, ne peut
> pas avoir un linkage "C".
oui. avec un compilo MS on utilise un modifier propriétaire
pour indiquer cela, avec GCC (ou autre) et les fonctions
POSIX, je n'ai aucune idée du moyen de faire cela, j'ai
supposé que cela existait.
>>> ignorer les exceptions
> Ce n'est pas ça qui m'intéressait. Je me posais la question
> sur leur transmission vers le thread appelant. Parfois, ça
> peut être utile que l'exception se propage à travers le
> join, pour se rétrouver dans le processus qui a démarrer le
> thread.
ok; en cas de terminaison anormale par exception (catchée et
traitée dans le thread secondaire), j'ai tendance à retourner
une copie de l'exception (ou un code d'erreur) par le même
mécanisme que celui qui poste les résultats (en gros envoi
d'une struct avec a) code d'execution (OK / KO) b) résultat).
James Kanze wrote on 14/09/2008 11:54:
> il faut que la fonction dont on passe l'adresse ait un
> linkage "C". Et une fonction membre, même static, ne peut
> pas avoir un linkage "C".
oui. avec un compilo MS on utilise un modifier propriétaire
pour indiquer cela, avec GCC (ou autre) et les fonctions
POSIX, je n'ai aucune idée du moyen de faire cela, j'ai
supposé que cela existait.
>>> ignorer les exceptions
> Ce n'est pas ça qui m'intéressait. Je me posais la question
> sur leur transmission vers le thread appelant. Parfois, ça
> peut être utile que l'exception se propage à travers le
> join, pour se rétrouver dans le processus qui a démarrer le
> thread.
ok; en cas de terminaison anormale par exception (catchée et
traitée dans le thread secondaire), j'ai tendance à retourner
une copie de l'exception (ou un code d'erreur) par le même
mécanisme que celui qui poste les résultats (en gros envoi
d'une struct avec a) code d'execution (OK / KO) b) résultat).
James Kanze wrote on 14/09/2008 11:54:
> il faut que la fonction dont on passe l'adresse ait un
> linkage "C". Et une fonction membre, même static, ne peut
> pas avoir un linkage "C".
oui. avec un compilo MS on utilise un modifier propriétaire
pour indiquer cela, avec GCC (ou autre) et les fonctions
POSIX, je n'ai aucune idée du moyen de faire cela, j'ai
supposé que cela existait.
>>> ignorer les exceptions
> Ce n'est pas ça qui m'intéressait. Je me posais la question
> sur leur transmission vers le thread appelant. Parfois, ça
> peut être utile que l'exception se propage à travers le
> join, pour se rétrouver dans le processus qui a démarrer le
> thread.
ok; en cas de terminaison anormale par exception (catchée et
traitée dans le thread secondaire), j'ai tendance à retourner
une copie de l'exception (ou un code d'erreur) par le même
mécanisme que celui qui poste les résultats (en gros envoi
d'une struct avec a) code d'execution (OK / KO) b) résultat).
Ça m'étonnerait un peu, d'ailleurs, que Windows n'exigent
pas réelement un linkage "C".
Ça m'étonnerait un peu, d'ailleurs, que Windows n'exigent
pas réelement un linkage "C".
Ça m'étonnerait un peu, d'ailleurs, que Windows n'exigent
pas réelement un linkage "C".
je voulais dire que c'est bien le cas, mais tu me fais douter.
je voulais dire que c'est bien le cas, mais tu me fais douter.
je voulais dire que c'est bien le cas, mais tu me fais douter.
Sylvain SF wrote on 15/09/2008 03:35:
je voulais dire que c'est bien le cas, mais tu me fais douter.
et dire des anneries.
la convention d'appel est imposé comme "nettoyage par la fonction"
mais la méthode statique passé en paramètre à "CreateThread"
(création d'un thread selon MS) n'est pas déclarée 'extern "C"'.
je n'avais jamais fait attention à ce "petit détail".
Sylvain SF wrote on 15/09/2008 03:35:
je voulais dire que c'est bien le cas, mais tu me fais douter.
et dire des anneries.
la convention d'appel est imposé comme "nettoyage par la fonction"
mais la méthode statique passé en paramètre à "CreateThread"
(création d'un thread selon MS) n'est pas déclarée 'extern "C"'.
je n'avais jamais fait attention à ce "petit détail".
Sylvain SF wrote on 15/09/2008 03:35:
je voulais dire que c'est bien le cas, mais tu me fais douter.
et dire des anneries.
la convention d'appel est imposé comme "nettoyage par la fonction"
mais la méthode statique passé en paramètre à "CreateThread"
(création d'un thread selon MS) n'est pas déclarée 'extern "C"'.
je n'avais jamais fait attention à ce "petit détail".
James Kanze wrote on 15/09/2008 02:27:
> Ça m'étonnerait un peu, d'ailleurs, que Windows n'exigent
> pas réelement un linkage "C".
je voulais dire que c'est bien le cas, mais tu me fais douter.
si linkage "à la C" ou "à la C++" signifie décoration
(mangling) des noms de fonctions, alors oui on doit utiliser
un "__stdcall" (qui est utilisé par toutes les API C de la
toolbox Win32).
si ce "mode de linkage" désigne autre chose, je n'ai aucune
idée des spécificités du linkeur MS.
James Kanze wrote on 15/09/2008 02:27:
> Ça m'étonnerait un peu, d'ailleurs, que Windows n'exigent
> pas réelement un linkage "C".
je voulais dire que c'est bien le cas, mais tu me fais douter.
si linkage "à la C" ou "à la C++" signifie décoration
(mangling) des noms de fonctions, alors oui on doit utiliser
un "__stdcall" (qui est utilisé par toutes les API C de la
toolbox Win32).
si ce "mode de linkage" désigne autre chose, je n'ai aucune
idée des spécificités du linkeur MS.
James Kanze wrote on 15/09/2008 02:27:
> Ça m'étonnerait un peu, d'ailleurs, que Windows n'exigent
> pas réelement un linkage "C".
je voulais dire que c'est bien le cas, mais tu me fais douter.
si linkage "à la C" ou "à la C++" signifie décoration
(mangling) des noms de fonctions, alors oui on doit utiliser
un "__stdcall" (qui est utilisé par toutes les API C de la
toolbox Win32).
si ce "mode de linkage" désigne autre chose, je n'ai aucune
idée des spécificités du linkeur MS.
Sylvain SF a écrit :
> Sylvain SF wrote on 15/09/2008 03:35:
>> je voulais dire que c'est bien le cas, mais tu me fais
>> douter.
> et dire des anneries.
> la convention d'appel est imposé comme "nettoyage par la
> fonction" mais la méthode statique passé en paramètre à
> "CreateThread" (création d'un thread selon MS) n'est pas
> déclarée 'extern "C"'.
> je n'avais jamais fait attention à ce "petit détail".
Je ne comprends toujours pas le problème. Si l'ABI est la
même[...]
alors les convention d'appel sont respectées et, à moins que
l'exception ne se propage jusqu'à la couche POSIX, il n'y a
pas de problème.
Sylvain SF a écrit :
> Sylvain SF wrote on 15/09/2008 03:35:
>> je voulais dire que c'est bien le cas, mais tu me fais
>> douter.
> et dire des anneries.
> la convention d'appel est imposé comme "nettoyage par la
> fonction" mais la méthode statique passé en paramètre à
> "CreateThread" (création d'un thread selon MS) n'est pas
> déclarée 'extern "C"'.
> je n'avais jamais fait attention à ce "petit détail".
Je ne comprends toujours pas le problème. Si l'ABI est la
même[...]
alors les convention d'appel sont respectées et, à moins que
l'exception ne se propage jusqu'à la couche POSIX, il n'y a
pas de problème.
Sylvain SF a écrit :
> Sylvain SF wrote on 15/09/2008 03:35:
>> je voulais dire que c'est bien le cas, mais tu me fais
>> douter.
> et dire des anneries.
> la convention d'appel est imposé comme "nettoyage par la
> fonction" mais la méthode statique passé en paramètre à
> "CreateThread" (création d'un thread selon MS) n'est pas
> déclarée 'extern "C"'.
> je n'avais jamais fait attention à ce "petit détail".
Je ne comprends toujours pas le problème. Si l'ABI est la
même[...]
alors les convention d'appel sont respectées et, à moins que
l'exception ne se propage jusqu'à la couche POSIX, il n'y a
pas de problème.
On Sep 15, 9:39 am, Michael DOUBEZ wrote:Sylvain SF a écrit :Sylvain SF wrote on 15/09/2008 03:35:
la convention d'appel est imposé comme "nettoyage par la
fonction" mais la méthode statique passé en paramètre à
"CreateThread" (création d'un thread selon MS) n'est pas
déclarée 'extern "C"'.
Je ne comprends toujours pas le problème. Si l'ABI est la
même[...]
C'est là précisement la question. Du point du vue de la norme,
c'est le linkage qui détermine l'ABI ; le C et le C++ ne sont
pas obligé à avoir le même linkage (et en partie, ne peut
l'avoir, puisque l'ABI du C++ précise aussi l'organisation de la
vtable, etc.). De même, Microsoft offre plusieurs linkage
différents (avec des ABI différentes) en guise d'extension.
alors les convention d'appel sont respectées et, à moins que
l'exception ne se propage jusqu'à la couche POSIX, il n'y a
pas de problème.
Mais les conventions d'appel dépendent du linkage. Je me suis
bien servi des compilateurs où les conventions étaient
différentes entre le C et le C++.
Si on ne peut guère concevoir
du cas sur une machine RISC type Sparc, il y a de fortes raisons
pour supporter de différentes conventions sur l'architecture
Intel.
On Sep 15, 9:39 am, Michael DOUBEZ <michael.dou...@free.fr> wrote:
Sylvain SF a écrit :
Sylvain SF wrote on 15/09/2008 03:35:
la convention d'appel est imposé comme "nettoyage par la
fonction" mais la méthode statique passé en paramètre à
"CreateThread" (création d'un thread selon MS) n'est pas
déclarée 'extern "C"'.
Je ne comprends toujours pas le problème. Si l'ABI est la
même[...]
C'est là précisement la question. Du point du vue de la norme,
c'est le linkage qui détermine l'ABI ; le C et le C++ ne sont
pas obligé à avoir le même linkage (et en partie, ne peut
l'avoir, puisque l'ABI du C++ précise aussi l'organisation de la
vtable, etc.). De même, Microsoft offre plusieurs linkage
différents (avec des ABI différentes) en guise d'extension.
alors les convention d'appel sont respectées et, à moins que
l'exception ne se propage jusqu'à la couche POSIX, il n'y a
pas de problème.
Mais les conventions d'appel dépendent du linkage. Je me suis
bien servi des compilateurs où les conventions étaient
différentes entre le C et le C++.
Si on ne peut guère concevoir
du cas sur une machine RISC type Sparc, il y a de fortes raisons
pour supporter de différentes conventions sur l'architecture
Intel.
On Sep 15, 9:39 am, Michael DOUBEZ wrote:Sylvain SF a écrit :Sylvain SF wrote on 15/09/2008 03:35:
la convention d'appel est imposé comme "nettoyage par la
fonction" mais la méthode statique passé en paramètre à
"CreateThread" (création d'un thread selon MS) n'est pas
déclarée 'extern "C"'.
Je ne comprends toujours pas le problème. Si l'ABI est la
même[...]
C'est là précisement la question. Du point du vue de la norme,
c'est le linkage qui détermine l'ABI ; le C et le C++ ne sont
pas obligé à avoir le même linkage (et en partie, ne peut
l'avoir, puisque l'ABI du C++ précise aussi l'organisation de la
vtable, etc.). De même, Microsoft offre plusieurs linkage
différents (avec des ABI différentes) en guise d'extension.
alors les convention d'appel sont respectées et, à moins que
l'exception ne se propage jusqu'à la couche POSIX, il n'y a
pas de problème.
Mais les conventions d'appel dépendent du linkage. Je me suis
bien servi des compilateurs où les conventions étaient
différentes entre le C et le C++.
Si on ne peut guère concevoir
du cas sur une machine RISC type Sparc, il y a de fortes raisons
pour supporter de différentes conventions sur l'architecture
Intel.