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

[prog c] Comment recuperer l'etat d'avancement d'une fonction ?

5 réponses
Avatar
smber
Bonjour,

Dans un programme C sous HP-UX, j'appelle une fonction d'une lib qui
tout au long de son execution va mettre à jour son etat d'avancement
dans une variable passée en parametre. Pendant le deroulement de la
fonction, je souhaiterai donc en parallèle aller verifier l'état de
l'avancement afin de l'afficher pour l'utilisateur (l'affichage est
géré à part, je ne m'en occupe pas ici).

Comment faire ? Suis-je obligé de faire du multithreading ou
existe-t-il une solution plus simple ?
Si la solution est de faire du multithreading, où trouver un exemple
simple ?

Merci d'avance,
Sebastien BERNARD2.

5 réponses

Avatar
Pascal Bourguignon
(Sebastien BERNARD2) writes:

Bonjour,

Dans un programme C sous HP-UX, j'appelle une fonction d'une lib qui
tout au long de son execution va mettre à jour son etat d'avancement
dans une variable passée en parametre. Pendant le deroulement de la
fonction, je souhaiterai donc en parallèle aller verifier l'état de
l'avancement afin de l'afficher pour l'utilisateur (l'affichage est
géré à part, je ne m'en occupe pas ici).

Comment faire ? Suis-je obligé de faire du multithreading ou
existe-t-il une solution plus simple ?


Si la fonction est prévue pour appeler un "callback", alors pas la
peine de faire du multithreading.

C'est typiquement quelque chose comme:

void call_back_print_progress(void* ref)
{
int progress=bibxyz_get_progress();
printf("rProgress: %3d %%");
}

bibxyz_function(arg1,arg2,call_back_print_progress,ref);

Ou, parfois:

bibxyz_install_call_back(call_back_print_progress,ref);
bibxyz_function(arg1,arg2);

Mais sinon, il faut faire du multithreading. Comme tu parle d'une
_variable_, c'est surement le cas.

Si la solution est de faire du multithreading, où trouver un exemple
simple ?


Ça dépend de la bibliothèque de thread disponible. Avec pthread,
quelque chose comme ça:


pthread_t worker_thread;
pthread_attr_t worker_thread_attr;
typedef struct {
int progress;
int working;
} worker_stuff_t;
worker_stuff_t worker_stuff;
int res;

void* worker_routine(void* pstuff)
{
worker_stuff_t* stuff=pstuff;
bibxyz_function(&(stuff->progress));
stuff->working=0;
return(0);
}

res=pthread_attr_init(&worker_thread_attr);
res=pthread_attr_setdetachstate(&worker_thread_attr,PTHREAD_CREATE_DETACHED);
worker_stuff.working=1;
res=pthread_create(&worker_thread,&worker_thread_attr,
worker_routine,&worker_stuff);
while(worker_stuff.working){
sleep(1);
printf("rProgress: %3d %%",worker_stuff.progress);
}

--
__Pascal_Bourguignon__
http://www.informatimago.com/

Avatar
DINH Viêt Hoà

void* worker_routine(void* pstuff)
{
worker_stuff_t* stuff=pstuff;
bibxyz_function(&(stuff->progress));
stuff->working=0;
return(0);
}

res=pthread_attr_init(&worker_thread_attr);
res=pthread_attr_setdetachstate(&worker_thread_attr,PTHREAD_CREATE_DETACHED);
worker_stuff.working=1;
res=pthread_create(&worker_thread,&worker_thread_attr,
worker_routine,&worker_stuff);
while(worker_stuff.working){
sleep(1);
printf("rProgress: %3d %%",worker_stuff.progress);
}


j'aurai personnellement, je n'aurais pas détaché le thread. Je préfère
détacher uniquement lorsque cela est nécessaire.
J'aurais plutôt mis un pipe ou un signal pour indiquer la fin du thread.

le thread signale au père qu'il a fini, avec :

- pthread_cond_timedwait() (s'il est disponible) pour attendre le signal
avec un délai maximum,

- ou sinon, un pipe avec un select() avec délai limité.

pour finir avec un pthread_join().

--
DINH V. Hoa,

"ça doit être une racaille pour être aussi con" -- Cent-Quarante-Six

Avatar
Pascal Bourguignon
DINH Viêt Hoà writes:


void* worker_routine(void* pstuff)
{
worker_stuff_t* stuff=pstuff;
bibxyz_function(&(stuff->progress));
stuff->working=0;
return(0);
}

res=pthread_attr_init(&worker_thread_attr);
res=pthread_attr_setdetachstate(&worker_thread_attr,PTHREAD_CREATE_DETACHED);
worker_stuff.working=1;
res=pthread_create(&worker_thread,&worker_thread_attr,
worker_routine,&worker_stuff);
while(worker_stuff.working){
sleep(1);
printf("rProgress: %3d %%",worker_stuff.progress);
}


j'aurai personnellement, je n'aurais pas détaché le thread. Je préfère
détacher uniquement lorsque cela est nécessaire.
J'aurais plutôt mis un pipe ou un signal pour indiquer la fin du thread.


Ça dépend de ce qu'on a à faire. Dans le cas de l'exemple, comme le
thread principal passe son temps à dormir ou à afficher le progrès, il
n'y a pas de raison de s'embêter avec des signaux: c'est synchrone!

le thread signale au père qu'il a fini, avec :

- pthread_cond_timedwait() (s'il est disponible) pour attendre le signal
avec un délai maximum,

- ou sinon, un pipe avec un select() avec délai limité.

pour finir avec un pthread_join().


À quoi ça sert d'envoyer un signal si on y met un délai limité ? On
risque de ne pas le voir passer et alors c'est comme si on n'avait
rien fait, non?


--
__Pascal_Bourguignon__
http://www.informatimago.com/


Avatar
DINH Viêt Hoà

Ça dépend de ce qu'on a à faire. Dans le cas de l'exemple, comme le
thread principal passe son temps à dormir ou à afficher le progrès, il
n'y a pas de raison de s'embêter avec des signaux: c'est synchrone!


en fait, c'est plus l'histoire du "DETACHED" qui m'ennuie.
J'ai l'impression qu'on ne contrôle plus trop ce qu'il se passe à côté.

le thread signale au père qu'il a fini, avec :

- pthread_cond_timedwait() (s'il est disponible) pour attendre le signal
avec un délai maximum,

- ou sinon, un pipe avec un select() avec délai limité.

pour finir avec un pthread_join().


À quoi ça sert d'envoyer un signal si on y met un délai limité ? On
risque de ne pas le voir passer et alors c'est comme si on n'avait
rien fait, non?


les variables condition en fait, sont toujours accompagnées par 2 autres
éléments : une variable d'état comme tu as mis, et un verrou (dont on ne
parlera pas ici).
Et il me semble qu'il faut réémettre le signal tant qu'il n'est pas
acquitté.

Enfin là, comme il nous faut l'affichage progressif, et donc, on a
bien de mettre à jour de temps en temps l'affichage. Enfin, comme dis le
man de rsync :

<<
--progress
This option tells rsync to print information showing the
progress of the transfer. This gives a bored user something to
watch.




(°v°)

--
DINH V. Hoa,

"ça doit être une racaille pour être aussi con" -- Cent-Quarante-Six


Avatar
Sébastien BERNARD
Merci. Je vais tester ça...

Sebastien BERNARD2.