documentation for dispatch_semaphore_wait
には、「信号のFIFO順で待機する」と記載されています。しかし、この例のようには見えません - 誰かが説明できますか?dispatch_semaphore_wait FIFOはありませんか?
例:
#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);
}
期待出力:
1:0
2:0
1:1
2:1
1:2
2:2
...
実際の出力(一例):
1:0
1:1
...
1:14
2:0 waited
2:1
...
編集:もし実際の出力ではなく、あるシリアルキューのq1とq2はグローバルキューに設定されます。
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
(時にはそれが完璧に動作しますが、時にはそれがこのような奇妙だ。)
感謝。しかし、q1とq2をグローバルキューにすると動作することがありますが、時には出力が完全に順不同です。私の編集を参照してください。なぜこれが起こっているのか? (もしそれがセマフォーか、並べ替えをやっているグローバルな待ち行列であるかわかりません) – jlstrecker
私の答えが更新されました。 –