2010-01-27 5 views
4

Sous Linux, si deux threads sont créés et tous les deux sont en cours d'exécution, lorsque l'un d'eux appelle recv() ou tout appel système IO qui se bloque lorsqu'aucune donnée n'est disponible, qu'arriverait-il au processus entier?Qu'advient-il des autres threads lorsqu'un thread est bloqué?

Est-ce que l'autre thread bloquera aussi? Je suppose que cela dépend de la façon dont le thread est implémenté. Si la bibliothèque de threads est dans l'espace utilisateur et que le noyau ignore totalement les threads dans le processus, alors process est l'entité de planification et ainsi les deux threads sont bloqués.

De plus, si l'autre thread ne bloque pas à cause de cette, peut-il alors send() données via la même prise, ce qui bloque le fil recv? Duplexing?

Des idées?

Répondre

1

Vous avez absolument raison de dire que le comportement de blocage dépend du fait que le thread est implémenté dans l'espace noyau ou dans l'espace utilisateur. Si le thread est implémenté uniquement dans l'espace utilisateur (c'est-à-dire que le noyau n'est pas impliqué dans le thread), tout point d'entrée bloquant dans le noyau doit être entouré de variantes non bloquantes qui peuvent simuler la sémantique de blocage de son appel. thread "(par exemple en utilisant AIO pour envoyer/recv données au lieu de bloquer, et le rappel de complétion rend le thread exécutable, encore une fois).

Dans Linux (et tous les autres systèmes d'exploitation majeurs existant, je peux penser), le filetage est mis en œuvre au niveau du noyau, ou similaire, et un appel de blocage dans le noyau pas, tous les autres threads pour bloquer.

Oui, vous pouvez send() à un socket pour lequel un autre thread est bloqué sur recv().

+0

Merci! une réponse assez complète. bon appel. – Figo

+0

Une question de plus, si des données sont arrivées au socket avant qu'un thread appelle recv(), le thread va-t-il réellement obtenir ces données? – Figo

+0

Oui. C'est vraiment la seule façon de travailler sur des sockets de datagramme non bloquants. Quelques petites notes, que j'ai l'intention d'aider - une, vous pouvez expérimenter avec ce genre de chose assez facilement. Ecrivez un petit programme qui acceptera une connexion, puis dormirez un moment, puis appelez 'recv' sur la nouvelle connexion.Utilisez 'nc' (netcat) ou quelque chose pour créer la connexion à votre serveur et y écrire des données immédiatement. Vous verrez que le serveur a reçu les mêmes données que vous avez envoyées. Deuxième remarque - c'est vraiment une troisième question distincte sur ce qui est généralement un forum de questions à la fois ... –

2

Le blocage des appels dans un thread ne devrait pas affecter les autres threads. Si le thread bloqué bloque un mutex avant d'entrer l'appel bloqué et que le second thread tente de verrouiller le même mutex, alors le second thread devra attendre que l'appel de blocage se termine et que le premier thread soit libéré le verrou.

+0

Merci, alors il tombe à la 2ème question: l'autre thread non-bloquant peut-il envoyer() des données via le même socket alors que recv() bloque un autre? Supposons UDP. – Figo

2

Il est tout à fait possible d'implémenter des threads dans l'espace utilisateur de sorte qu'un thread puisse continuer tandis qu'un autre thread thread sur I/O.

Le thread non bloqué devrait pouvoir envoyer sur le socket pendant que l'autre thread le bloque (j'ai écrit un tel code).

+0

Merci, c'est une excellente nouvelle. – Figo

+0

Seulement possible si les syscalls supportent les appels non bloquants pour tout. Très possible de bloquer tous les threads utilisateur sur quelque chose comme fstat pendant plusieurs secondes. –

+0

@Zan Lynx: Il parle de Linux, qui a les appels système aio_read() et aio_write() POSIX. –

Questions connexes