{"id":756,"date":"2013-01-30T16:51:34","date_gmt":"2013-01-30T16:51:34","guid":{"rendered":"https:\/\/raspberry-projects.com\/pi\/?p=756"},"modified":"2014-09-26T15:05:28","modified_gmt":"2014-09-26T15:05:28","slug":"using-semaphores","status":"publish","type":"post","link":"https:\/\/raspberry-projects.com\/pi\/programming-in-c\/semaphores\/using-semaphores","title":{"rendered":"Using Semaphores"},"content":{"rendered":"<p>\nSemaphores allow processes to avoid clashes when accessing shared resources, for instance shared memory.\n<\/p>\n<h4>\nGenerating A Random Key<br \/>\n<\/h4>\n<p>\nHumans aren&#39;t very good at picking random values so use a site like this one: <a href=\"http:\/\/www.random.org\/integers\/\" target=\"_blank\">www.random.org\/integers\/<\/a>\n<\/p>\n<p>\nIt won&#39;t do a 32bit 1 to 2147483647, but it will do 1 to 1000000000\n<\/p>\n<h4>\nSimple Example Of Creating &amp; Using A Semaphore<br \/>\n<\/h4>\n<h5>\nHeader Files Needed<br \/>\n<\/h5>\n<pre>\r\n<code>\r\n#include &lt;sys\/sem.h&gt;\t\t\/\/Used for semaphores\r\n<\/code><\/pre>\n<p>\n&nbsp;\n<\/p>\n<h5>\nDefining The Semaphore Your Header File<br \/>\n<\/h5>\n<pre>\r\n<code>\r\n\/\/----- SEMAPHORE -----\r\n\/\/On linux systems this union is probably already defined in the included sys\/sem.h, but if not use this default basic definition:\r\nunion semun {\r\n\tint val;\r\n\tstruct semid_ds *buf;\r\n\tunsigned short *array;\r\n};\r\n\r\n\/\/FUNCTIONS:\r\nstatic int semaphore1_get_access(void);\r\nstatic int semaphore1_release_access(void);\r\n\/\/VARIABLES:\r\nstatic int semaphore1_id;\r\n<\/code><\/pre>\n<h5>\nThe Functions<br \/>\n<\/h5>\n<pre>\r\n<code>\r\n\r\n\/\/***********************************************************\r\n\/\/***********************************************************\r\n\/\/********** WAIT IF NECESSARY THEN LOCK SEMAPHORE **********\r\n\/\/***********************************************************\r\n\/\/***********************************************************\r\n\/\/Wait if necessary and then change the semaphore by &ndash;1. This is the &quot;wait&quot; operation\r\nstatic int semaphore1_get_access(void)\r\n{\r\n\tstruct sembuf sem_b;\r\n\tsem_b.sem_num = 0;\r\n\tsem_b.sem_op = -1; \/* P() *\/\r\n\tsem_b.sem_flg = SEM_UNDO;\r\n\tif (semop(semaphore1_id, &amp;sem_b, 1) == -1)\t\t\/\/Wait until free\r\n\t{\r\n\t\tfprintf(stderr, &quot;semaphore1_get_access failed\\n&quot;);\r\n\t\treturn(0);\r\n\t}\r\n\treturn(1);\r\n}\r\n\r\n\/\/***************************************\r\n\/\/***************************************\r\n\/\/********** RELEASE SEMAPHORE **********\r\n\/\/***************************************\r\n\/\/***************************************\r\n\/\/Setting the semaphore back to available.  This is the &quot;release&quot; operation.\r\n\r\nstatic int semaphore1_release_access(void)\r\n{\r\n\tstruct sembuf sem_b;\r\n\tsem_b.sem_num = 0;\r\n\tsem_b.sem_op = 1; \/* V() *\/\r\n\tsem_b.sem_flg = SEM_UNDO;\r\n\tif (semop(semaphore1_id, &amp;sem_b, 1) == -1)\r\n\t{\r\n\t\tfprintf(stderr, &quot;semaphore1_release_access failed\\n&quot;);\r\n\t\treturn(0);\r\n\t}\r\n\treturn(1);\r\n}\r\n<\/code><\/pre>\n<h5>\nCreate The Semaphore<br \/>\n<\/h5>\n<pre>\r\n<code>\r\n\t\/\/----------------------------\r\n\t\/\/----- CREATE SEMAPHORE -----\r\n\t\/\/----------------------------\r\n\tprintf(&quot;Creating semaphore...\\n&quot;);\r\n\tsemaphore1_id = semget((key_t)12345, 1, 0666 | IPC_CREAT);\t\t\/\/&lt;&lt;&lt;&lt;&lt; SET THE SEMPAHORE KEY   (Semaphore key, number of semaphores required, flags)\r\n\t\/\/\tSemaphore key\r\n\t\/\/\t\tUnique non zero integer (usually 32 bit).  Needs to avoid clashing with another other processes semaphores (you just have to pick a random value and hope - ftok() can help with this but it still doesn&#39;t guarantee to avoid colision)\r\n\r\n\t\/\/Initialize the semaphore using the SETVAL command in a semctl call (required before it can be used)\r\n\tunion semun sem_union_init;\r\n\tsem_union_init.val = 1;\r\n\tif (semctl(semaphore1_id, 0, SETVAL, sem_union_init) == -1)\r\n\t{\r\n\t\tfprintf(stderr, &quot;Creating semaphore failed to initialize\\n&quot;);\r\n\t\texit(EXIT_FAILURE);\r\n\t}\r\n<\/code><\/pre>\n<h5>\nUsing The Semaphore<br \/>\n<\/h5>\n<pre>\r\n<code>\r\n\t\/\/----- SEMAPHORE GET ACCESS -----\r\n\tif (!semaphore1_get_access())\r\n\t\texit(EXIT_FAILURE);\r\n\r\n\t\/\/... do the interlocked action ...\r\n\r\n\t\/\/----- SEMAPHORE RELEASE ACCESS -----\r\n\tif (!semaphore1_release_access())\r\n\t\texit(EXIT_FAILURE);\r\n<\/code><\/pre>\n<h5>\nDeleting The Semaphore<br \/>\n<\/h5>\n<pre>\r\n<code>\r\n\t\/\/----------------------------\r\n\t\/\/----- DELETE SEMAPHORE -----\r\n\t\/\/----------------------------\r\n\t\/\/It&#39;s important not to unintentionally leave semaphores existing after program execution. It also may cause problems next time you run the program.\r\n\tunion semun sem_union_delete;\r\n\tif (semctl(semaphore1_id, 0, IPC_RMID, sem_union_delete) == -1)\r\n\t\tfprintf(stderr, &quot;Failed to delete semaphore\\n&quot;);\r\n<\/code><\/pre>\n<p>\n&nbsp;\n<\/p>\n<p>\n&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Semaphores allow processes to avoid clashes when accessing shared resources, for instance shared memory. Generating A Random Key Humans aren&#39;t very good at picking random values so use a site like this one: www.random.org\/integers\/ It won&#39;t do a 32bit 1 to 2147483647, but it will do 1 to 1000000000 Simple Example Of Creating &amp; Using [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[45],"tags":[],"class_list":["post-756","post","type-post","status-publish","format-standard","hentry","category-semaphores"],"_links":{"self":[{"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/posts\/756","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/comments?post=756"}],"version-history":[{"count":5,"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/posts\/756\/revisions"}],"predecessor-version":[{"id":1764,"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/posts\/756\/revisions\/1764"}],"wp:attachment":[{"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/media?parent=756"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/categories?post=756"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/tags?post=756"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}