os_cp:threads
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| os_cp:threads [2024/04/18 09:42] – [Accessing the same data from multiple threads] jkonczak | os_cp:threads [2025/04/25 11:55] (current) – [POSIX condition variables] jkonczak | ||
|---|---|---|---|
| Line 69: | Line 69: | ||
| \\ | \\ | ||
| < | < | ||
| - | <a href=" | + | <a href=" |
| '' | '' | ||
| '' | '' | ||
| Line 132: | Line 132: | ||
| \\ | \\ | ||
| < | < | ||
| - | <a href=" | + | <a href=" |
| '' | '' | ||
| < | < | ||
| Line 209: | Line 209: | ||
| \\ | \\ | ||
| < | < | ||
| - | <a href=" | + | <a href=" |
| '' | '' | ||
| < | < | ||
| Line 275: | Line 275: | ||
| POSIX offers a mechanism called // | POSIX offers a mechanism called // | ||
| thread a cancellation request using the | thread a cancellation request using the | ||
| - | '' | + | '' |
| function. Each thread can select is behaviour on receiving such request using the | function. Each thread can select is behaviour on receiving such request using the | ||
| - | '' | + | '' |
| and | and | ||
| - | '' | + | '' |
| functions. One may either allow or disallow cancalling a thread, and one may | functions. One may either allow or disallow cancalling a thread, and one may | ||
| choose whether the cancallation should ouccur immediatly after a request, or | choose whether the cancallation should ouccur immediatly after a request, or | ||
| at the next cancallation point. Cancellation points are the execution points | at the next cancallation point. Cancellation points are the execution points | ||
| of several pthread functions, among which notably | of several pthread functions, among which notably | ||
| - | '' | + | '' |
| is there just to this end. | is there just to this end. | ||
| Once the thread complies to the cancellation request, it roughly does the same | Once the thread complies to the cancellation request, it roughly does the same | ||
| Line 401: | Line 401: | ||
| \\ | \\ | ||
| < | < | ||
| - | <a href=" | + | <a href=" |
| '' | '' | ||
| < | < | ||
| Line 408: | Line 408: | ||
| \\ | \\ | ||
| < | < | ||
| - | <a href=" | + | <a href=" |
| '' | '' | ||
| '' | '' | ||
| Line 420: | Line 420: | ||
| \\ | \\ | ||
| < | < | ||
| - | <a href=" | + | <a href=" |
| '' | '' | ||
| < | < | ||
| \\ | \\ | ||
| and finally set the attributes using corresponding functions: | and finally set the attributes using corresponding functions: | ||
| - | * < | + | * < |
| - | * < | + | * < |
| - | * < | + | * < |
| - | * < | + | * < |
| The mutex type impacts what happens when a mutex that is already locked is | The mutex type impacts what happens when a mutex that is already locked is | ||
| Line 452: | Line 452: | ||
| \\ | \\ | ||
| < | < | ||
| - | <a href=" | + | <a href=" |
| '' | '' | ||
| '' | '' | ||
| < | < | ||
| \\ | \\ | ||
| - | < | + | < |
| '' | '' | ||
| < | < | ||
| Line 472: | Line 472: | ||
| \\ | \\ | ||
| < | < | ||
| - | <a href=" | + | <a href=" |
| '' | '' | ||
| < | < | ||
| Line 618: | Line 618: | ||
| \\ | \\ | ||
| To create a rwlock one has to create a '' | To create a rwlock one has to create a '' | ||
| - | it with either '' | + | it with either '' |
| \\ | \\ | ||
| A read-write lock can be locked with: | A read-write lock can be locked with: | ||
| - | * '' | + | * '' |
| - | * '' | + | * '' |
| < | < | ||
| \\ | \\ | ||
| - | To unlock a rwlock (locked in any mode), '' | + | To unlock a rwlock (locked in any mode), '' |
| Line 704: | Line 704: | ||
| ===== Critical sections, deadlocks ===== | ===== Critical sections, deadlocks ===== | ||
| - | ~~Exercise.# | + | ~~Exercise.# |
| - | ~~Exercise.# | + | ~~Exercise.# |
| ~~Exercise.# | ~~Exercise.# | ||
| - | < | + | < |
| - | <small> | + | <code c> |
| - | < | + | … |
| - | #include < | + | 10│ struct myIO {FILE *in; FILE *out;}; |
| - | #include < | + | 11│ void* threadFunc(void *num); |
| - | #include < | + | … |
| - | #include < | + | 17│ struct { |
| - | #include < | + | 18│ pthread_mutex_t mtx; |
| - | + | 19│ char text[256]; | |
| - | struct { | + | 20│ } item[5]; |
| - | pthread_mutex_t mtx; | + | 21│ |
| - | char text[256]; | + | 22│ int main(int argc, char **argv) { |
| - | } item[5]; | + | … |
| - | + | 28│ | |
| - | const char *arg0; | + | 29│ |
| - | + | 30│ | |
| - | void *threadFunc(intptr_t | + | 31│ |
| - | char name[1024], cmd[1024]; | + | 32│ } |
| - | | + | 33│ |
| - | | + | 34│ } |
| - | | + | 35│ |
| - | | + | 36│ void *threadFunc(void* numRaw) { |
| - | + | 37│ | |
| - | while (1) { | + | 38│ |
| - | char line[1024], nl; | + | |
| - | | + | 48│ while (1) { |
| - | + | 49│ | |
| - | int argOne = atoi(line); | + | 50│ |
| - | if (argOne >= 5 || argOne < 0) | + | 51│ char line[1024]; |
| - | | + | 52│ fgets(line, 1024, win.in); |
| - | + | 53│ | |
| - | | + | 54│ |
| - | + | 55│ int argOne = atoi(line); | |
| - | if (!argTwoTxt) { | + | … |
| - | pthread_mutex_lock(& | + | 61│ char *argTwoTxt = strchr(line, |
| - | | + | 62│ |
| - | pthread_mutex_unlock(& | + | 63│ if (!argTwoTxt) { |
| - | continue; | + | 65│ pthread_mutex_lock(& |
| - | } | + | 66│ |
| - | + | 67│ pthread_mutex_unlock(& | |
| - | argTwoTxt++; | + | 68│ continue; |
| - | char *e; | + | 69│ } |
| - | int argTwo = strtol(argTwoTxt, | + | 70│ |
| - | + | 71│ argTwoTxt++; | |
| - | if (!*e && argTwo < 5 && argTwo >= 0 && argOne != argTwo) { | + | 72│ char *e; |
| - | pthread_mutex_lock(& | + | 73│ int argTwo = strtol(argTwoTxt, |
| - | pthread_mutex_lock(& | + | 74│ |
| - | | + | 75│ if (!*e && argTwo < 5 && argTwo >= 0 && argOne != argTwo) { |
| - | memcpy(item[argOne].text, | + | 77│ pthread_mutex_lock(& |
| - | pthread_mutex_unlock(& | + | 78│ pthread_mutex_lock(& |
| - | pthread_mutex_unlock(& | + | 79│ |
| - | } else { | + | 80│ memcpy(item[argOne].text, |
| - | pthread_mutex_lock(& | + | 81│ pthread_mutex_unlock(& |
| - | | + | 82│ pthread_mutex_unlock(& |
| - | memset(item[argOne].text, | + | 83│ } else { |
| - | strncpy(item[argOne].text, | + | 85│ pthread_mutex_lock(& |
| - | pthread_mutex_unlock(& | + | 86│ |
| - | } | + | 87│ memset(item[argOne].text, |
| - | } | + | 88│ strncpy(item[argOne].text, |
| - | } | + | 89│ pthread_mutex_unlock(& |
| - | + | 90│ } | |
| - | int main(int argc, char **argv) { | + | 91│ } |
| - | | + | 92│ } |
| - | + | | |
| - | printf(" | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | | + | |
| - | + | ||
| - | for (int i = 0; i < 5; ++i) | + | |
| - | pthread_mutex_init(& | + | |
| - | + | ||
| - | for (intptr_t i = 1; i < 5; ++i) { | + | |
| - | pthread_t tid; | + | |
| - | pthread_create(& | + | |
| - | pthread_detach(tid); | + | |
| - | } | + | |
| - | threadFunc(0); | + | |
| - | } | + | |
| </ | </ | ||
| - | </ | ||
| < | < | ||
| Line 820: | Line 801: | ||
| \\ | \\ | ||
| < | < | ||
| - | <a href=" | + | <a href=" |
| '' | '' | ||
| < | < | ||
| \\ | \\ | ||
| - | < | + | < |
| '' | '' | ||
| \\ | \\ | ||
| Line 896: | Line 877: | ||
| When one thread needs to execute some logic once a specific condition is fulfilled, | When one thread needs to execute some logic once a specific condition is fulfilled, | ||
| it should: | it should: | ||
| + | < | ||
| + | <WRAP group> | ||
| + | <WRAP half column> | ||
| - lock a mutex, | - lock a mutex, | ||
| - check the condition, | - check the condition, | ||
| - | - if the condition is false: | + | - while the condition is false: |
| - wait on a condition variable, | - wait on a condition variable, | ||
| - go back to step 2, | - go back to step 2, | ||
| - do the logic, | - do the logic, | ||
| - unlock the mutex. | - unlock the mutex. | ||
| + | </ | ||
| + | <WRAP half column> | ||
| + | < | ||
| + | <pre class=" | ||
| + | <span style=" | ||
| + | <span class=" | ||
| + | <span style=" | ||
| + | < | ||
| + | <span style=" | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| A thread that may change the state and thus affect the condition should: | A thread that may change the state and thus affect the condition should: | ||
| + | < | ||
| + | <WRAP group> | ||
| + | <WRAP half column> | ||
| - lock the mutex, | - lock the mutex, | ||
| - do its logic, | - do its logic, | ||
| - signal the condition variable, | - signal the condition variable, | ||
| - unlock the mutex((One can also signal the condition variable after unlocking the mutex.)). | - unlock the mutex((One can also signal the condition variable after unlocking the mutex.)). | ||
| + | </ | ||
| + | <WRAP half column> | ||
| + | < | ||
| + | <pre class=" | ||
| + | <span style=" | ||
| + | < | ||
| + | <span style=" | ||
| + | <span style=" | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| < | < | ||
| The example conditions include: | The example conditions include: | ||
| + | < | ||
| * a boolean flag is set; the flag indicates that another thread finished a part of the computation and the results can used, | * a boolean flag is set; the flag indicates that another thread finished a part of the computation and the results can used, | ||
| * a list of items is not empty; the list contains tasks to be done by this thread, | * a list of items is not empty; the list contains tasks to be done by this thread, | ||
| Line 920: | Line 933: | ||
| \\ | \\ | ||
| < | < | ||
| - | <a href=" | + | <a href=" |
| '' | '' | ||
| < | < | ||
| Line 928: | Line 941: | ||
| \\ | \\ | ||
| < | < | ||
| - | <a href=" | + | <a href=" |
| '' | '' | ||
| < | < | ||
| Line 936: | Line 949: | ||
| \\ | \\ | ||
| < | < | ||
| - | <a href=" | + | <a href=" |
| '' | '' | ||
| < | < | ||
| Line 945: | Line 958: | ||
| \\ | \\ | ||
| < | < | ||
| - | <a href=" | + | <a href=" |
| '' | '' | ||
| '' | '' | ||
os_cp/threads.1713433320.txt.gz · Last modified: (external edit)