{"id":21041904,"url":"https://github.com/ahota/shmemaphore","last_synced_at":"2026-04-21T21:32:47.394Z","repository":{"id":208679041,"uuid":"722216416","full_name":"ahota/shmemaphore","owner":"ahota","description":"Example of using semaphores to synchronize communication over shared memory between two separate processes","archived":false,"fork":false,"pushed_at":"2024-05-23T04:59:59.000Z","size":441,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-05-23T05:34:40.126Z","etag":null,"topics":["c","cplusplus","interprocess-communication","semaphore","shared-memory"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ahota.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-11-22T17:24:46.000Z","updated_at":"2024-06-05T17:13:41.007Z","dependencies_parsed_at":null,"dependency_job_id":"3d72e5f0-8d6b-42f4-947d-93d009ab081e","html_url":"https://github.com/ahota/shmemaphore","commit_stats":null,"previous_names":["ahota/sem_shm"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahota%2Fshmemaphore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahota%2Fshmemaphore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahota%2Fshmemaphore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahota%2Fshmemaphore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ahota","download_url":"https://codeload.github.com/ahota/shmemaphore/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243489289,"owners_count":20298990,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","cplusplus","interprocess-communication","semaphore","shared-memory"],"created_at":"2024-11-19T13:56:40.891Z","updated_at":"2025-12-29T21:17:42.343Z","avatar_url":"https://github.com/ahota.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Semaphore Shared Memory example\n\nThis is an example of using semaphores to synchronize communication over\nshared memory between two separate processes. The two processes, `server` and\n`client`, use two semaphores and two shared memory segments to communicate.\n\nThe two semaphores are used to signal when each process is done accessing\nshared memory.  The two shared memory segments are a \"header\" segment and a\n\"data\" segment.  The header segment is used to describe the size and metadata\nof the contents of the data segment.\n\n## Communication overview\n\n`server` will ask for a file from the client. The name of the file is chosen\nat random, and the length (bytes) of this filename is placed in the header\nsegment. This is done so `client` knows how many bytes to read from the data\nsegment. The filename is then dropped into the data segment. `server`\nincrements its semaphore, letting `client` know that it's done. `server` then\nwaits to decrement the client semaphore; it is blocked until `client` is\nfinished.\n\n`client` then reads the length of the filename from the header segment, and\nthen reads that many bytes from the data segment. With the filename known,\n`client` loads the file. The size of the file is then placed into the header\nsegment, overwriting the previous value. In this case, since the file is an\nimage, the dimensions and number of channels are also written to the header\nsegment. `client` then writes the image file's bytes to the data segment and\nincrements its semaphore, letting `server` know the file is ready to be read.\n\nFinally, `server` is unblocked and can read the header segment to determine\nhow to read the file in the data segment.\n\n## Required knowledge\n\n`server` and `client` need to know a few things to cooperate.\n\n* The two semaphore names must be known by both processes\n  * POSIX named semaphores are used because they exist as a file outside the\n    processes memory spaces.  Unnamed semaphores cannot be used because they\n    exist only within the current process' memory. System V semaphores are not\n    used because they are ancient\n* The two shared memory segment names must be known by both processes\n\n## API\n\n* The `server` command is a string whose length is placed in the header\n  segment as a single `uint64_t`.\n* The `client` response is an image file. The total number of bytes, the\n  dimensions of the image, and the number of channels in the image are placed\n  in the header segment as an array of 4 `uint64_t`\n* Shared memory segments can be resized up, but not down. This shaves off a\n  bit of time when varying size files are sent because the OS is not\n  re-allocating shared memory with each command and response\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fahota%2Fshmemaphore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fahota%2Fshmemaphore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fahota%2Fshmemaphore/lists"}