Je vois que la question a été réactivée avec une prime, demandant maintenant quelles en sont les utilisations pratiques yield
. Je vais donner un exemple de mon expérience.
Comme nous le savons, yield
force le thread appelant à abandonner le processeur sur lequel il s'exécute afin qu'un autre thread puisse être programmé pour s'exécuter. Ceci est utile lorsque le thread en cours a terminé son travail pour le moment mais veut revenir rapidement au début de la file d'attente et vérifier si une condition a changé. En quoi est-ce différent d'une variable de condition? dit essentiellement "autoriser un thread différent à fonctionner, mais permettez-moi de me remettre au travail très rapidement car je m'attends à ce que quelque chose change très très rapidement dans mon état". Cela fait allusion à une rotation occupée, où une condition peut changer rapidement mais la suspension du thread entraînerait une perte de performances importante.yield
permet au thread de revenir beaucoup plus rapidement à un état d'exécution. Lors de l'attente d'une variable de condition, le thread est suspendu et doit attendre qu'un autre thread signale qu'il doit continuer.yield
Mais assez de babillage, voici un exemple concret: le motif parallèle du front d'onde. Un exemple de base de ce problème est le calcul des «îlots» individuels de 1 dans un tableau bidimensionnel rempli de 0 et de 1. Un «îlot» est un groupe de cellules adjacentes les unes aux autres verticalement ou horizontalement:
1 0 0 0
1 1 0 0
0 0 0 1
0 0 1 1
0 0 1 1
Ici, nous avons deux îles de 1: en haut à gauche et en bas à droite.
Une solution simple consiste à effectuer un premier passage sur l'ensemble du tableau et à remplacer les valeurs 1 par un compteur incrémentiel de sorte qu'à la fin, chaque 1 soit remplacé par son numéro de séquence dans l'ordre principal de la ligne:
1 0 0 0
2 3 0 0
0 0 0 4
0 0 5 6
0 0 7 8
Dans l'étape suivante, chaque valeur est remplacée par le minimum entre elle-même et les valeurs de ses voisins:
1 0 0 0
1 1 0 0
0 0 0 4
0 0 4 4
0 0 4 4
Nous pouvons maintenant facilement déterminer que nous avons deux îles.
La partie que nous voulons exécuter en parallèle est l'étape où nous calculons les minimums. Sans entrer trop dans les détails, chaque thread obtient des lignes de manière entrelacée et s'appuie sur les valeurs calculées par le thread traitant la ligne ci-dessus. Ainsi, chaque thread doit être légèrement en retard par rapport au thread traitant la ligne précédente, mais doit également suivre le rythme dans un délai raisonnable. Plus de détails et une mise en œuvre sont présentés par moi-même dans ce document . Notez que l'utilisation de sleep(0)
qui est plus ou moins l'équivalent C de yield
.
Dans ce cas, yield
on a utilisé pour forcer chaque thread à se mettre en pause, mais comme le thread traitant la ligne adjacente avançait très rapidement entre-temps, une variable de condition s'avérerait un choix désastreux.
Comme vous pouvez le voir, yield
c'est une optimisation assez fine. L'utiliser au mauvais endroit, par exemple attendre une condition qui change rarement, entraînera une utilisation excessive du processeur.
Désolé pour le long babillage, j'espère que je me suis fait comprendre.