DISPATCH_SEMAPHORE_SIGNAL(3)
β¨ NAME β¨
dispatch_semaphore_create, dispatch_semaphore_signal, dispatch_semaphore_wait β synchronized counting semaphore π
so yeah bestie, this is the dispatch_semaphore_create(3) page from the Library Functions Manual, and we're talking semaphores today. no cap, they're lowkey iconic.
π SYNOPSIS π
#include <dispatch/dispatch.h>
dispatch_semaphore_t
dispatch_semaphore_create(long count);
long
dispatch_semaphore_signal(dispatch_semaphore_t semaphore);
long
dispatch_semaphore_wait(dispatch_semaphore_t semaphore,
dispatch_time_t timeout);
π¦ DESCRIPTION π¦
okay so dispatch semaphores are literally the tool you use to synchronize threads. that's the whole vibe. π«Ά
and the timeout parameter? you can make that with the dispatch_time(3) or dispatch_walltime(3) functions. iykyk β¨
πΈ COMPLETION SYNCHRONIZATION πΈ
if count is equal to zero, then your semaphore is giving "wait for the work to be done" energy. perfect for synchronizing completion of work. for example:
sema = dispatch_semaphore_create(0);
dispatch_async(queue, ^{
foo();
dispatch_semaphore_signal(sema);
});
bar();
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
like, bar() runs, then we wait for foo() to signal. main character scheduling fr fr π
π FINITE RESOURCE POOL π
if count is greater than zero, then the semaphore is the girlboss of managing a finite pool of resources. for example, a library that wants to limit Unix descriptor usage:
sema = dispatch_semaphore_create(getdtablesize() / 4);
at each Unix FD allocation:
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
fd = open("/etc/services", O_RDONLY);
when each FD is closed:
close(fd);
dispatch_semaphore_signal(sema);
it's giving responsible resource management, we love to see it π
π RETURN VALUES π
- the
dispatch_semaphore_create()function returnsNULLif no memory is available, or if thecountparameter is less than zero π - the
dispatch_semaphore_signal()function returns non-zero when a thread is woken. otherwise, zero is returned β¨ - the
dispatch_semaphore_wait()function returns zero upon success and non-zero after the timeout expires. if the timeout isDISPATCH_TIME_FOREVER, thendispatch_semaphore_wait()waits forever and always returns zero. forever. no takebacks π°οΈ
π§ MEMORY MODEL π§
dispatch semaphores are retained and released via calls to dispatch_retain() and dispatch_release(). that's the whole thing, keep it balanced bestie π
π CAVEATS π
dispatch semaphores are strict counting semaphores. in other words, dispatch semaphores do not saturate at any particular value.
saturation can be achieved through atomic compare-and-swap logic. what follows is a saturating binary semaphore:
void
saturating_semaphore_signal(dispatch_semaphore_t dsema, int *sent)
{
if (__sync_bool_compare_and_swap(sent, 0, 1)) {
dispatch_semaphore_signal(dsema);
}
}
void
saturating_semaphore_wait(dispatch_semaphore_t dsema, int *sent)
{
*sent = 0;
dispatch_semaphore_wait(dsema, DISPATCH_TIME_FOREVER);
}
like, the counting just keeps counting. no ceiling. you want a ceiling, you build it yourself with that compare-and-swap, periodt π
π SEE ALSO π
and that's the tea, bestie π this lil masterpiece comes to you from Darwin, dated May 1, 2009, and the page is dispatch_semaphore_create(3). go forth and synchronize your threads, you're gonna eat π₯πβ¨
π¦ where this page comes from
- ubuntu jammy: libdispatch-dev 0~svn197-3.3ubuntu2
- Copyright (c) 2008-2009 Apple Inc. All rights reserved
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms