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

comment savoir si des données sont attendues en stdin ?

20 réponses
Avatar
Kobayashi
Bonjour à tous,

J'ai un programme fortran auquel je ne peux
pas toucher qui lit des données sur l'entrée
standard, fait des traitements plus ou moins
longs, puis attend des nouvelles données sur
l'entrée standard. J'aimerais pouvoir savoir
quand des données sont attendues (pour savoir
que le traitement précédent est terminé) ...

Un petit exemple :

PROGRAM MAIN
WRITE(6,*)'Enter the number of seconds to sleep ...'
READ(5,*)NUMBER
WRITE(6,*)'Sleeping for ',NUMBER,'seconds'
DO I=0,NUMBER-1
CALL SLEEP(1)
WRITE(6,*)I+1
ENDDO
WRITE(6,*)'Enter a number ...'
READ(5,*)NUMBER
WRITE(6,*)'Number is: ',NUMBER
END

J'aimerais pouvoir lancer ce programme par une
manière quelconque (system, fork, ...) et avoir
un moyen de savoir quand le programme en est aux
lignes "READ" en interrogeant je ne sais quoi
(un super pipe, un fichier de /proc, ...). En gros,
je veux quelque chose qui me réponde 1 en arrivant
au premier READ, 0 pendant toute la boucle avec
les sleep, puis 1 en arrivant au second READ.

Je cherche, je cherche mais sans trouver pour le
moment ... Si quelqu'un a une idée !

Cordialement,

K.

10 réponses

1 2
Avatar
Paul Gaborit
À (at) Mon, 31 May 2010 21:35:48 +0200,
Kobayashi écrivait (wrote):

J'ai un programme fortran auquel je ne peux
pas toucher qui lit des données sur l'entrée
standard, fait des traitements plus ou moins
longs, puis attend des nouvelles données sur
l'entrée standard. J'aimerais pouvoir savoir
quand des données sont attendues (pour savoir
que le traitement précédent est terminé) ...

Un petit exemple :

PROGRAM MAIN
WRITE(6,*)'Enter the number of seconds to sleep ...'
READ(5,*)NUMBER
WRITE(6,*)'Sleeping for ',NUMBER,'seconds'
DO I=0,NUMBER-1
CALL SLEEP(1)
WRITE(6,*)I+1
ENDDO
WRITE(6,*)'Enter a number ...'
READ(5,*)NUMBER
WRITE(6,*)'Number is: ',NUMBER
END

J'aimerais pouvoir lancer ce programme par une
manière quelconque (system, fork, ...) et avoir
un moyen de savoir quand le programme en est aux
lignes "READ" en interrogeant je ne sais quoi
(un super pipe, un fichier de /proc, ...). En gros,
je veux quelque chose qui me réponde 1 en arrivant
au premier READ, 0 pendant toute la boucle avec
les sleep, puis 1 en arrivant au second READ.



Le plus simple en suivant l'exemple ci-dessus serait de surveiller ce
qu'afficher le programme pour détecter les WRITE qui précèdent les READ
(un peu à la manière de 'expect')... Mais j'imagine que ce n'est pas
possible avec le programme réel.

Sinon, via procfs, il y a bien /proc/PID/syscall qui donne comme premier
nombre le numéro de l'appel système en cours. Sur ma machine, on trouve
ces numéros dans /usr/include/asm/unistd_32.h et le 3 correspond à
'read'...

--
Paul Gaborit - <http://perso.mines-albi.fr/~gaborit/>
Avatar
Bruno Tréguier
Kobayashi wrote:

J'aimerais pouvoir lancer ce programme par une
manière quelconque (system, fork, ...) et avoir
un moyen de savoir quand le programme en est aux
lignes "READ" en interrogeant je ne sais quoi
(un super pipe, un fichier de /proc, ...). En gros,
je veux quelque chose qui me réponde 1 en arrivant
au premier READ, 0 pendant toute la boucle avec
les sleep, puis 1 en arrivant au second READ.

Je cherche, je cherche mais sans trouver pour le
moment ... Si quelqu'un a une idée !

Cordialement,

K.



Bonjour,

Essayez de regarder du côté de l'appel système "select(2)", il est fait
exactement pour ça. Extrait du man:

select() and pselect() allow a program to monitor multiple file
descriptors, waiting until one or more of the file descriptors become
"ready" for some class of I/O operation (e.g., input possible). A file
descriptor is considered ready if it is possible to perform the
corresponding I/O operation (e.g., read(2)) without blocking.


Donc, en gros, il vous faut un "wrapper" dans un langage quelconque, qui
possède dans son API une possibilité s'appel à select(). Bien sûr, il y
a le C, mais ça peut aussi être du Perl, par exemple, avec la fonction
IO::Select, ou autre chose encore.

Cordialement,

Bruno
Avatar
Kobayashi
Le 31/05/2010 23:42, Paul Gaborit a écrit :

À (at) Mon, 31 May 2010 21:35:48 +0200,
Kobayashi écrivait (wrote):

J'ai un programme fortran auquel je ne peux
pas toucher qui lit des données sur l'entrée
standard, fait des traitements plus ou moins
longs, puis attend des nouvelles données sur
l'entrée standard. J'aimerais pouvoir savoir
quand des données sont attendues (pour savoir
que le traitement précédent est terminé) ...

Un petit exemple :

PROGRAM MAIN
WRITE(6,*)'Enter the number of seconds to sleep ...'
READ(5,*)NUMBER
WRITE(6,*)'Sleeping for ',NUMBER,'seconds'
DO I=0,NUMBER-1
CALL SLEEP(1)
WRITE(6,*)I+1
ENDDO
WRITE(6,*)'Enter a number ...'
READ(5,*)NUMBER
WRITE(6,*)'Number is: ',NUMBER
END

J'aimerais pouvoir lancer ce programme par une
manière quelconque (system, fork, ...) et avoir
un moyen de savoir quand le programme en est aux
lignes "READ" en interrogeant je ne sais quoi
(un super pipe, un fichier de /proc, ...). En gros,
je veux quelque chose qui me réponde 1 en arrivant
au premier READ, 0 pendant toute la boucle avec
les sleep, puis 1 en arrivant au second READ.





Bonjour Paul,


Le plus simple en suivant l'exemple ci-dessus serait de surveiller ce
qu'afficher le programme pour détecter les WRITE qui précèdent les READ
(un peu à la manière de 'expect')... Mais j'imagine que ce n'est pas
possible avec le programme réel.



Effectivement, ce n'est pas possible dans le cas réel.

Sinon, via procfs, il y a bien /proc/PID/syscall qui donne comme premier
nombre le numéro de l'appel système en cours. Sur ma machine, on trouve
ces numéros dans /usr/include/asm/unistd_32.h et le 3 correspond à
'read'...




Merci pour cette piste ... J'ai essayé et il semble que
lorsque le code en est à READ, le syscall est à l'état 0,
bizarre ! En tout état de cause, syscall est à un état
différent pendant le traitement donc c'est une piste
à explorer.

Cordialement,

K.
Avatar
Kobayashi
Le 02/06/2010 10:11, Bruno Tréguier a écrit :
Kobayashi wrote:

J'aimerais pouvoir lancer ce programme par une
manière quelconque (system, fork, ...) et avoir
un moyen de savoir quand le programme en est aux
lignes "READ" en interrogeant je ne sais quoi
(un super pipe, un fichier de /proc, ...). En gros,
je veux quelque chose qui me réponde 1 en arrivant
au premier READ, 0 pendant toute la boucle avec
les sleep, puis 1 en arrivant au second READ.

Je cherche, je cherche mais sans trouver pour le
moment ... Si quelqu'un a une idée !

Cordialement,

K.



Bonjour,



Bonjour Bruno,


Essayez de regarder du côté de l'appel système "select(2)", il est fait
exactement pour ça. Extrait du man:

select() and pselect() allow a program to monitor multiple file
descriptors, waiting until one or more of the file descriptors become
"ready" for some class of I/O operation (e.g., input possible). A file
descriptor is considered ready if it is possible to perform the
corresponding I/O operation (e.g., read(2)) without blocking.


Donc, en gros, il vous faut un "wrapper" dans un langage quelconque, qui
possède dans son API une possibilité s'appel à select(). Bien sûr, il y
a le C, mais ça peut aussi être du Perl, par exemple, avec la fonction
IO::Select, ou autre chose encore.



Merci, je vais regarder ceci attentivement !

Cordialement,

K.


Cordialement,

Bruno
Avatar
Paul Gaborit
À (at) Wed, 02 Jun 2010 22:30:44 +0200,
Kobayashi écrivait (wrote):

Merci pour cette piste ... J'ai essayé et il semble que
lorsque le code en est à READ, le syscall est à l'état 0,
bizarre !



Voici un exemple de sortie de /proc/PID/syscall lorsqu'un programme est
bloqué sur un appel système 'read' :

3 0x0 0x9518178 0x50 0x9518008 0xbffeb1ac 0xbffeb138 0xbffeb114 0x15a422

(ce n'est pas dépendant du langage utilisé.)

Peut-être que l'appel système 'read' vaut 0 sur votre système...

--
Paul Gaborit - <http://perso.mines-albi.fr/~gaborit/>
Avatar
Paul Gaborit
À (at) Wed, 02 Jun 2010 22:33:56 +0200,
Kobayashi écrivait (wrote):

Le 02/06/2010 10:11, Bruno Tréguier a écrit :
Donc, en gros, il vous faut un "wrapper" dans un langage quelconque, qui
possède dans son API une possibilité s'appel à select(). Bien sûr, il y
a le C, mais ça peut aussi être du Perl, par exemple, avec la fonction
IO::Select, ou autre chose encore.



Merci, je vais regarder ceci attentivement !



Cela ne répondra pas à votre probléme car 'select' déclenche lorsqu'on
peut écrire à un processus et non lorsque celui-ci essaye de lire. Il y
aurait simultanéité si les tampons de communication entre processus
étaient de taille nulle (mais ce n'est pas le cas).

--
Paul Gaborit - <http://perso.mines-albi.fr/~gaborit/>
Avatar
Paul Gaborit
À (at) Wed, 02 Jun 2010 23:26:54 +0200,
Kobayashi écrivait (wrote):

Sur mandriva 2010 32bits, je n'ai même pas le fichier syscall !!
Snif ! Alors que je l'avais en 64 bits ...



En fait, 'syscall' n'est pas vraiment documenté dans proc(5). Ce n'est
donc pas étonnant qu'il ne soit pas présent partout.

Dans le même ordre d'idée, je viens de voir le fichier wchan :

"""
wchan WCHAN name of the kernel function in which the process is
sleeping
"""

qui contient "read_chan" lorsque mon process est sur READ
et autre chose pendant le traitement. Intéressant !



C'est peut-être une piste plus simple à exploiter (mais /proc/PID/wchan
n'est pas plus documenté que syscall dans proc(5)).

Il y a aussi la ligne 'State:' dans /proc/PID/status qui permet de
savoir si le processus est dans l'état 'S (sleeping)' (ce qui est le cas
d'un processus qui est bloqué sur un appel à 'read').

--
Paul Gaborit - <http://perso.mines-albi.fr/~gaborit/>
Avatar
Dominique MICOLLET
Kobayashi wrote:

Effectivement, ce n'est pas possible dans le cas réel.



Pour ma curiosité, pourriez-vous décrire le contexte dans lequel vous devez
implanter cette "usine à gaz" parce que j'ai du mal à imaginer comment, en
environnement Unix, on peut se trouver dans une situation où l'on a pas
accès au résultats des E/S d'une application quelle qu'elle soit.

--
Dominique MICOLLET
Adresse email : enlever deux francs
Avatar
Lucas Levrel
Le 3 juin 2010, Dominique MICOLLET a écrit :

Kobayashi wrote:

Effectivement, ce n'est pas possible dans le cas réel.



Pour ma curiosité, pourriez-vous décrire le contexte dans lequel vous devez
implanter cette "usine à gaz" parce que j'ai du mal à imaginer comment, en
environnement Unix, on peut se trouver dans une situation où l'on a pas
accès au résultats des E/S d'une application quelle qu'elle soit.



S'il n'y a pas de write avant chaque read ?

--
LL
Avatar
Lucas Levrel
Le 3 juin 2010, Bruno Tréguier a écrit :

Vous avez effectivement raison, Paul, mais en y réfléchissant, n'est-ce pas
fonctionnellement équivalent ? Dans la mesure où le tampon conserve les
données, j'ai du mal à concevoir une raison pour laquelle le processus qui
écrit devrait attendre que son "copain" soit réellement en attente sur un
read...



Par exemple si l'entrée à faire dépend des sorties... (s'il faut connaître
toutes les sorties produites jusqu'à l'appel à read)

--
LL
1 2