Package Exports
- sysv-semaphore
- sysv-semaphore/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (sysv-semaphore) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
sysv-semaphore
Node.js bindings for Unix System V Semaphores.
Should work on any system that supports System V semaphores. YMMV. If it breaks, let me know, or better still fix it and make a PR.
Requirements
- Node.js 14.x or later
- A Unix-like operating system with System V IPC support
- Prebuilt binaries supported: Linux (x64, arm64, i386) OSX (x64, arm64)
- otherwise, C++ build tools (for native compilation)
Installation
npm install sysv-semaphore
For other platforms, the module will be built from source during installation.
Usage
A simple API that uses the Unix System V semget
family of system calls to create and use semaphores.
All operations are performed with SEM_UNDO
ensuring that semaphores are released by the kernel when the process exits.
API Reference
Creating/Opening Semaphores
// Create a semaphore, but only if one does not already exist
const sem = Semaphore.createExclusive('/path/to/some/file', 10);
// Open an existing semaphore, or create it if it doesn't exist
const sem = Semaphore.create('/path/to/some/file', 10);
// Open an existing semaphore
const sem = Semaphore.open('/path/to/some/file');
Semaphore Operations
// Block waiting for the semaphore (not recommended in most cases)
sem.wait();
sem.wait(1);
// Block waiting for the semaphore to be greater then the value (not recommended in most cases)
sem.wait(10);
// Non-blocking attempt to acquire semaphore
if (sem.trywait()) {
// Critical section
}
if (sem.trywait(1)) {
// Critical section
}
// Aquire multiple units
if (sem.trywait(10)) {
// Critical section
}
// Get current value
const value = sem.valueOf();
// Release one unit
sem.post();
// Release multiple units
sem.post(10);
// get number of references to this semaphore
sem.refs();
// Clean up
sem.close();
Basic Example
// myModule.js
const { Semaphore } = require('sysv-semaphore');
// Create a module-scoped semaphore
// Initial value of 1 makes this a mutex/binary semaphore
const mutex = Semaphore.create('/path/to/some/file', 1);
// Example function that uses the semaphore
async function doSomethingExclusive() {
if (mutex.trywait()) {
try {
// Critical section
console.log('Acquired semaphore');
await someAsyncWork();
} finally {
// Release the semaphore
mutex.post();
}
} else {
console.log('Semaphore was not available');
}
}
// Another example with a counting semaphore
const poolSemaphore = Semaphore.create('/path/to/some/file', 5); // Allow 5 concurrent operations
async function useResourcePool() {
// Aquire 2 resources
if (poolSemaphore.trywait(2)) {
try {
// Use the aquired resources
await doSomeWork();
} finally {
// Release 2 resources
poolSemaphore.post(2);
}
} else {
// Pool is full, handle accordingly
}
}
// Semaphores will be automatically cleaned up when the process exits
Best Practices
- Always use
try/finally
blocks to ensure semaphores are properly closed - Prefer
trywait()
overwait()
to avoid blocking the Node.js event loop - Use
create()
instead ofcreateExclusive()
for better crash recovery - Keep critical sections as short as possible
- Handle errors appropriately - check
error.code
for specific error conditions
Error Handling
All operations can throw system errors. The error object will have:
error.code
: Standard Node.js error codes (e.g., 'EACCES', 'EINVAL')error.message
: Includes the failing system call name
Common error codes:
** refer to your systems manual page for the syscall in the error message **
EACCES
: Permission deniedEEXIST
: Semaphore exists (with createExclusive)ENOENT
: Semaphore does not existEINVAL
: Invalid argument
Troubleshooting
Semaphore not being released:
- Ensure
close()
is called in afinally
block - Check if process crashed while holding semaphore
- Ensure
Permission errors:
- Check file permissions of the key file
- Verify user has appropriate system permissions
Resource limits:
- Check system semaphore limits (
ipcs -l
) - Clean up unused semaphores (
ipcs -s
to list,ipcrm
to remove)
- Check system semaphore limits (
Notes on Garbage Collection
While the Node.js garbage collector will eventually clean up semaphores, it's best practice to explicitly call close()
when done. This ensures:
- Timely resource release
- Predictable cleanup
- Better system resource management
License
This is free software with no warranty expressed or implied. If it breaks you get to keep both pieces. See the LICENSE
.