This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
os_cp:semaphores:solutions [2023/05/10 09:38] jkonczak utworzono |
os_cp:semaphores:solutions [2023/09/15 15:18] (current) jkonczak |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | |||
<html><div style="line-height:1em"></html> | <html><div style="line-height:1em"></html> | ||
+ | |||
+ | |||
+ | ~~Exercise.#~~ | ||
+ | <code c> | ||
+ | #include <fcntl.h> | ||
+ | #include <semaphore.h> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | int main() { | ||
+ | sem_t *mySemaphore = sem_open("/mySemaphore", O_CREAT | O_EXCL, 0666, 0); | ||
+ | if (mySemaphore == SEM_FAILED) { | ||
+ | perror("Creating the semaphore failed"); | ||
+ | return 1; | ||
+ | } | ||
+ | sem_wait(mySemaphore); | ||
+ | return 0; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | <code c> | ||
+ | #include <fcntl.h> | ||
+ | #include <semaphore.h> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | int main() { | ||
+ | sem_t *mySemaphore = sem_open("/mySemaphore", 0, 0666, 0); | ||
+ | if (mySemaphore == SEM_FAILED) { | ||
+ | perror("Opening the semaphore failed"); | ||
+ | return 1; | ||
+ | } | ||
+ | sem_post(mySemaphore); | ||
+ | return 0; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ~~Exercise.#~~ | ||
+ | |||
<code c> | <code c> | ||
#include <fcntl.h> | #include <fcntl.h> | ||
Line 79: | Line 115: | ||
} | } | ||
</code> | </code> | ||
+ | |||
+ | ~~Exercise.#~~ | ||
+ | |||
+ | Line: | ||
+ | <code c> if (createSucceeded) sleep(10);</code> | ||
+ | added anywhere after line 13 and before line 22 delays the first process from | ||
+ | initializing the semaphore for 10 seconds. If another process attempts to wait | ||
+ | on uninitialized semaphore, it is likely to get stuck forever. | ||
+ | |||
+ | ~~Exercise.#~~ | ||
+ | |||
+ | Lines between ''sem_wait'' and ''sem_post'' are the critical region. | ||
+ | |||
+ | ~~Exercise.#~~ | ||
+ | |||
+ | When the program is run concurrently with arguments ''0 1'' and ''1 0'', it will | ||
+ | deadlock if both processes manage to acquire the first semaphore (respectively | ||
+ | ''0'' for the first process, and ''1'' for the second) and then try to acquire | ||
+ | the second one (respectively ''1'' and ''0''). | ||
+ | |||
+ | ~~Exercise.#~~ | ||
+ | |||
+ | One of the simpler solutions is to wait on semaphores in a predefined order, | ||
+ | that is instead of: | ||
+ | <code c> | ||
+ | sem_wait(&data->item[argOne].sem); | ||
+ | sem_wait(&data->item[argTwo].sem); | ||
+ | </code> | ||
+ | one may just: | ||
+ | <code c> | ||
+ | sem_wait(&data->item[argOne<argTwo?argOne:argTwo].sem); | ||
+ | sem_wait(&data->item[argOne<argTwo?argTwo:argOne].sem); | ||
+ | </code> | ||
+ | | ||
<html></div></html> | <html></div></html> | ||
+ | |||
+ | |||
+ | ~~META: | ||
+ | language = en | ||
+ | ~~ | ||
+ |