Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Passage d'un tableau en paramètre d'un thread

7 réponses
Avatar
gna
Bonjour,
voici mon problème...

Dans mon main je reçois le tableau de variables ARGV[]
argv[0] étant le nom de mon programme compilé et les autres argv[ n ] étant des paramètres que j'utilise.

J'aimerais faire de mon programme un multithread, donc j'ai ma fonction main qui contient mes threads et j'ai ma fonction appellée "conversion" extérieur au main qui accomplit des taches.

J'aimerais déclarer mes threads comme ceci:
HANDLE thread1 = ::CreateThread( NULL, 0, Function, "tout mon tableau argv" , 0, NULL );

Comment faire passer mon tableau de variable dans mon thread, et comment les récupérer par la suite dans ma fonction extérieur au main.

Merci d'avance

7 réponses

Avatar
xylo
Le Thu, 16 Oct 2008 07:04:16 -0500, gna a écrit:

Bonjour,
voici mon problème...

Dans mon main je reçois le tableau de variables ARGV[]
argv[0] étant le nom de mon programme compilé et les autres argv[ n ] étant des
paramètres que j'utilise.

J'aimerais faire de mon programme un multithread, donc j'ai ma fonction main
qui contient mes threads et j'ai ma fonction appellée "conversion" extérieur au
main qui accomplit des taches.

J'aimerais déclarer mes threads comme ceci:
HANDLE thread1 = ::CreateThread( NULL, 0, Function, "tout mon tableau argv" ,
0, NULL );

Comment faire passer mon tableau de variable dans mon thread, et comment les
récupérer par la suite dans ma fonction extérieur au main.

Merci d'avance



salut, je te conseille de poster sur fr.comp.lang.c++

--
Apply rot13 to this e-mail address before using it.
JM Marino
http://jm.marino.free.fr
Avatar
Marc Boyer
On 2008-10-16, gna wrote:
Bonjour,
voici mon problème...

Dans mon main je reçois le tableau de variables ARGV[]
argv[0] étant le nom de mon programme compilé et les autres argv[ n ] étant des
paramètres que j'utilise.

J'aimerais faire de mon programme un multithread, donc j'ai ma fonction main
qui contient mes threads et j'ai ma fonction appellée "conversion" extérieur au
main qui accomplit des taches.

J'aimerais déclarer mes threads comme ceci:
HANDLE thread1 = ::CreateThread( NULL, 0, Function, "tout mon tableau argv" ,
0, NULL );



Ben, sans connaitre la signature de CreateThread, c'est difficile.
M'enfin bon, je suppose que ça prend un void*, alors pourquoi tu ne fais pas
HANDLE thread1 = ::CreateThread( NULL, 0, Function, argv , 0, NULL );

Comment faire passer mon tableau de variable dans mon thread, et comment les
récupérer par la suite dans ma fonction extérieur au main.



Quelle fonction extérieur au main ?

Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. André Maurois)
Avatar
oksid
gna wrote:
J'aimerais déclarer mes threads comme ceci:
HANDLE thread1 = ::CreateThread( NULL, 0, Function, "tout mon tableau argv" ,
0, NULL );

Comment faire passer mon tableau de variable dans mon thread, et comment les
récupérer par la suite dans ma fonction extérieur au main.



Hello,

Les "::" avant CreateThread sont du C++, pas du C.

La documentation Microsoft montre comment passer une structure
à une fonction d'entrée de thread.
http://msdn.microsoft.com/en-us/library/ms682516(VS.85).aspx

Une des solutions à votre problème pourrait se coder en C comme ceci:

/*********************************************************/
#include <windows.h>
#include <stdio.h>


DWORD WINAPI func(LPVOID lpParam)
{
char **argv = (char**)lpParam;
int i = 0;

while (argv[i] != NULL) {
printf("argv[%d] = %sn", i, argv[i]);
i++;
}
return 0;
}

int main(int argc, char *argv[])
{
HANDLE thread1;

thread1 = CreateThread( NULL, 0, func, argv, 0, NULL);
if (thread1 != NULL) {
WaitForSingleObject(thread1, INFINITE);
}
printf("thread principal %pn", thread1);
system("pause");
return 0;
}

/*********************************************************/
Avatar
Charlie Gordon
"oksid" a écrit dans le message de news:
a491d$48f83f0f$50533917$
gna wrote:
J'aimerais déclarer mes threads comme ceci:
HANDLE thread1 = ::CreateThread( NULL, 0, Function, "tout mon tableau
argv" ,
0, NULL );

Comment faire passer mon tableau de variable dans mon thread, et comment
les
récupérer par la suite dans ma fonction extérieur au main.



Hello,

Les "::" avant CreateThread sont du C++, pas du C.

La documentation Microsoft montre comment passer une structure
à une fonction d'entrée de thread.
http://msdn.microsoft.com/en-us/library/ms682516(VS.85).aspx

Une des solutions à votre problème pourrait se coder en C comme ceci:

/*********************************************************/
#include <windows.h>
#include <stdio.h>


DWORD WINAPI func(LPVOID lpParam)
{
char **argv = (char**)lpParam;
int i = 0;

while (argv[i] != NULL) {
printf("argv[%d] = %sn", i, argv[i]);
i++;
}
return 0;
}

int main(int argc, char *argv[])
{
HANDLE thread1;

thread1 = CreateThread( NULL, 0, func, argv, 0, NULL);
if (thread1 != NULL) {
WaitForSingleObject(thread1, INFINITE);
}
printf("thread principal %pn", thread1);
system("pause");
return 0;
}



Pour ramener le sujet sur le C, remarquons que le printf imprime la valeur
du HANDLE de thread thread1 après que celui-ci ait terminé sa courte
existence. Ceci pose deux problèmes :
- le format %p attend un argument de type void* (ou éventuellement char*),
on fait donc la supposition que le type HANDLE est un alias d'un de ces
types, voire un pointeur de même représentation.
- le simple fait de manipuler un pointeur, ne serait-ce que pour en passer
la valeur à printf, n'est pas loisible après que l'objet pointé a été
libéré. En pratique, cela ne pose pas de problème avec win32 ou win64, mais
ce n'est pas strictement correct si le HANDLE peut être libéré. Ce qui
signifie donc que le résultat de CreateThread ne devrait jamais être
manipulé ou qu'il ne devrait jamais être libéré. Comme il est indispensable
de pouvoir utiliser les HANDLE de thread, cela signifie que les handle de
thread doivent être recyclés avec une méthode adéquate.

Ce recyclage semble facile, mais c'est un leurre : rien n'empêche en effet
le thread func de créer toute une lignée d'autres threads et de mourir bien
avant que le test if (thread1 != NULL) ne soit éxécuté.
- Si les HANDLE ne sont pas recyclés, et une simple boucle qui crée un
thread et attend sa fin va plus ou moins rapidement épuiser les ressources
du système.
- Si en revanche les HANDLE sont recyclés, il est possible que thread1 soit
réutilisé par le système pour désigner un autre thread parmi la nombreuse
progéniture engendrée par func, donc toute la belle mécanique qui suppose
que le programmeur sait quel thread est référencé par thread1 s'écroule.

Le recyclage ne peut donc pas être automatique. Sous Windows, il doit être
fait explicitement par le programmeur qui doit "libérer" le HANDLE en
appelant CloseHandle(thread1). Le code ci-dessus peut donc tout-à-fait
manipuler thread1 après la fin du thread correspondant, mais ne devrait
toutefois pas faire de supposition sur le type de HANDLE. Dans le monde
réel, il n'est pas rare que les HANDLE de threads ne soient jamais libérés
par CloseHandle et donc que les ressources du système soient progressivement
consommées par les services toujours plus nombreux installés automatiquement
par la moindre application Windows (système d'impression, demon de
mise-à-jour, gestion de périphérique, anti-malware, quick-launch...). Les
utilisateurs de Windows reconnaitront un comportement bien connu ;-)

Et je n'ai même pas effleuré le sujet : les problématiques de rendez-vous,
de sémaphores, de verrous, d'accès concurrents aux données partagées, de
dead locks sont autrement plus ardues à maitriser...

Moralité : les threads, c'est un art difficile, une mécanique subtile qui
pose des problèmes compliqués et dont les bugs sont souvent impossibles à
occire. Bref, c'est MAL, et il faut éviter le plus possible.

--
Chqrlie.
Avatar
gna
xylo a écrit le 16/10/2008 à 21h03 :
Le Thu, 16 Oct 2008 07:04:16 -0500, gna a écrit:

Bonjour,
voici mon problème...

Dans mon main je reçois le tableau de variables ARGV[]
argv[0] étant le nom de mon programme compilé et les autres
argv[ n ] étant des
paramètres que j'utilise.

J'aimerais faire de mon programme un multithread, donc j'ai ma fonction main
qui contient mes threads et j'ai ma fonction appellée
"conversion" extérieur au
main qui accomplit des taches.

J'aimerais déclarer mes threads comme ceci:
HANDLE thread1 = ::CreateThread( NULL, 0, Function, "tout mon tableau
argv" ,
0, NULL );

Comment faire passer mon tableau de variable dans mon thread, et comment les
récupérer par la suite dans ma fonction extérieur au
main.

Merci d'avance




salut, je te conseille de poster sur fr.comp.lang.c++

--
Apply rot13 to this e-mail address before using it.
JM Marino
http://jm.marino.free.fr


merci à tous pour votre aide
Avatar
Antoine Leca
En news:, gna va escriure:
J'aimerais faire de mon programme un multithread,



Quelle plateforme ?
Et si tu te sers d'une plateforme spécifique, tu auras de bien meilleurs
réponses en utilisant les groupes dédiés à cette plateforme.


HANDLE thread1 = ::CreateThread(



Huh? Une réponse adaptée à C++ a peu de chances de t'être fournie ici (ou
alors ce serait par erreur...)
Et le passage de données tabulaires (en fait même la manière de concevoir le
modèle de données à ce niveau) est typiquement assez différent entre C et
C++ (vector<> etc.)

Donc ÀMHA tu aurais dû poster ailleurs.


comment les récupérer par la suite dans ma fonction extérieur au main.



C'est quoi pour toi une fonction extérieure à main() ?
En C (environnement hébergé) --et AQJS en C++ aussi-- une des idées de base
est justement que tout « dépend » de main(), qu'il n'y a rien en dehors de
main...

Si par « fonction extérieure » tu veux désigner un sous-programme que main()
appelerait, il suffit de lui passer le tableau comme paramètre au moment où
tu l'appelles (aucun problème a priori), et ensuite de gérer correctement
les accés concurrents du fait de l'architecture "multi-thread".



Antoine
Avatar
-ed-
On 16 oct, 13:04, gna wrote:
Bonjour,
voici mon problème...

Dans mon main je reçois le tableau de variables ARGV[]
argv[0] étant le nom de mon programme compilé et les autres argv[ n ] étant des
paramètres que j'utilise.

J'aimerais faire de mon programme un multithread, donc j'ai ma fonction m ain
qui contient mes threads et j'ai ma fonction appellée "conversion" ext érieur au
main qui accomplit des taches.

J'aimerais déclarer mes threads comme ceci:
HANDLE thread1 = ::CreateThread( NULL, 0, Function, "tout mon tableau a rgv" ,
0, NULL );

Comment faire passer mon tableau de variable dans mon thread, et comment les
récupérer par la suite dans ma fonction extérieur au main.



#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

struct arg
{
int argc;
char **argv;
};

void *tache (void *user)
{
if (user != NULL)
{
struct arg *p_arg = user;

int i;
for (i = 0; i < p_arg->argc; i++)
{
printf ("'%s'n", p_arg->argv[i]);
}
}
return NULL;
}

/* Programme principal */
int main (int argc, char **argv)
{
pthread_t t;
struct arg data;

data.argc = argc;
data.argv = argv;

pthread_create (&t, NULL, tache, &data);
pthread_join (t, NULL);
puts ("thread secondaire terminé.");
return 0;
}

'C:devhellobinDebughello.exe'
'in.txt'
'out.txt'
thread secondaire terminÚ.

Process returned 0 (0x0) execution time : 0.039 s
Press any key to continue.