Le documentation for dispatch_semaphore_wait
indique qu'il "attend dans l'ordre FIFO pour un signal". Mais il ne semble pas dans cet exemple-- quelqu'un peut-il expliquer s'il vous plaît?Est-ce que dispatch_semaphore_wait n'est pas FIFO?
Exemple:
#include <dispatch/dispatch.h>
#include <stdio.h>
dispatch_queue_t q1, q2;
dispatch_semaphore_t sem;
int g_call;
void do_work(void)
{
int s = 0;
int i;
for (i = 0; i < 100000000; ++i)
++s;
}
void f1(int call)
{
__block int waited = 0;
dispatch_async(q1, ^{
while (dispatch_semaphore_wait(sem, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC/1000)))
waited = 1;
printf("1:%d %s\n", call, waited ? "waited" : "");
do_work();
dispatch_semaphore_signal(sem);
});
}
void f2(int call)
{
__block int waited = 0;
dispatch_async(q2, ^{
while (dispatch_semaphore_wait(sem, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC/1000)))
waited = 1;
printf("\t\t2:%d %s\n", call, waited ? "waited" : "");
do_work();
dispatch_semaphore_signal(sem);
});
}
int main(int argc, char **argv)
{
q1 = dispatch_queue_create(NULL, NULL);
q2 = dispatch_queue_create(NULL, NULL);
sem = dispatch_semaphore_create(1);
g_call = 0;
dispatch_queue_t q_global = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, q_global);
const uint64_t DELAY = 10;
dispatch_source_set_event_handler(timer, ^{
f1(g_call);
f2(g_call);
++g_call;
dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, DELAY), 0, 0);
});
dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, DELAY), 0, 0);
dispatch_resume(timer);
sleep(3);
}
Résultats attendus:
1:0
2:0
1:1
2:1
1:2
2:2
...
sortie réelle (un exemple):
1:0
1:1
...
1:14
2:0 waited
2:1
...
Modifier: puissance effective si, au lieu de files d'attente étant en série , q1 et q2 sont définis sur la file d'attente globale:
1:0
2:8 waited
1:3 waited
1:4 waited
2:3 waited
1:6 waited
1:9 waited
2:9 waited
2:21
1:28 waited
(Parfois, il fonctionne parfaitement, mais parfois, il est bizarre comme ça.)
Merci pour le explanation-- qui aide. Mais si je fais q1 et q2 la file d'attente globale, parfois ça marche mais parfois les sorties sont totalement hors service. Voir mes modifications. Une idée de pourquoi cela se passe? (Je ne suis pas sûr que ce soit les sémaphores ou la file d'attente globale qui fait le réordonnancement.) – jlstrecker
Mis à jour ma réponse. –