# [2022q1](http://wiki.csie.ncku.edu.tw/sysprog/schedule) 第 10 週測驗題 ###### tags: `linux2022` :::info 目的: 檢驗學員對 **[Linux 核心設計: 不僅是個執行單元的 Process](https://hackmd.io/@sysprog/linux-process)** 和 **[並行和多執行緒程式設計](https://hackmd.io/@sysprog/concurrency)** 的認知 ::: 作答表單: * ==[測驗 `1`](https://docs.google.com/forms/d/e/1FAIpQLSfwGzix-optnhZtlZ_S_s2hXKZ56vIxLCGvceENIhUrUp1C9Q/viewform)== (Linux 核心設計) ### 測驗 `1` 在 [Linux 核心設計: 不僅是個執行單元的 Process](https://hackmd.io/@sysprog/linux-process) 提及 [futex](https://man7.org/linux/man-pages/man2/futex.2.html),我們可用來實作 lock,可見: * [Linux futex based Read-Write Lock implementation](https://smoku.xiaoka.com/post/147930509718/linux-futex-based-read-write-lock-implementation) * [Basics of Futexes](https://eli.thegreenplace.net/2018/basics-of-futexes/) 在 [並行程式設計: POSIX Thread](https://hackmd.io/@sysprog/posix-threads),提及案例: "Mutex and Semaphore" (你今天用對 mutex 了嗎?),提醒要留意細節。參考 [man page `pthread_mutex_unlock()`](https://linux.die.net/man/3/pthread_mutex_lock) 裏面提到: > If the mutex type is **`PTHREAD_MUTEX_DEFAULT`**, attempting to recursively lock the mutex results in undefined behavior. **Attempting to unlock the mutex if it was not locked by the calling thread results in undefined behavior.** Attempting to unlock the mutex if it is not locked results in undefined behavior. 仔細地看 [man page `pthread_mutex_unlock()`](https://linux.die.net/man/3/pthread_mutex_lock) 會發現: > If the mutex type is **`PTHREAD_MUTEX_ERRORCHECK`**, then error checking shall be provided. If a thread attempts to relock a mutex that it has already locked, an error shall be returned. **If a thread attempts to unlock a mutex that it has not locked or a mutex which is unlocked, an error shall be returned.** 我們需要在初始化 mutex 之際,就指定型態。 `mu` 是我們嘗試使用 futex 的多執行緒執行環境的實作,介面比照 POSIX Thread,針對 Linux/x86-64,程式碼可見: [mu](https://gist.github.com/jserv/03f0a6c9c72b70464f2fd0295cbc936d) (部分遮蔽) 預期執行結果: (地址可能會不同) ``` [thread main] Testing normal mutex [thread 0x55fd427bd010] Trying to actuire the mutex succeeded [thread 0x55fd427bd080] Trying to actuire the mutex failed [thread 0x55fd427bd010] Starting normal mutex test [thread 0x55fd427bd048] Trying to actuire the mutex failed [thread 0x55fd427bd0b8] Trying to actuire the mutex failed [thread 0x55fd427bd0f0] Trying to actuire the mutex failed [thread main] Threads spawned successfully [thread main] Sleeping 7 seconds [thread 0x55fd427bd010] Finishing normal mutex test [thread 0x55fd427bd080] Starting normal mutex test [thread 0x55fd427bd080] Finishing normal mutex test [thread 0x55fd427bd048] Starting normal mutex test [thread 0x55fd427bd048] Finishing normal mutex test [thread 0x55fd427bd0b8] Starting normal mutex test [thread 0x55fd427bd0b8] Finishing normal mutex test [thread 0x55fd427bd0f0] Starting normal mutex test [thread 0x55fd427bd0f0] Finishing normal mutex test --- [thread main] Testing errorcheck mutex [thread main] Threads spawned successfully [thread main] Sleeping 5 seconds [thread 0x55fd427bd010] Starting errorcheck mutex test [thread 0x55fd427bd010] Trying to lock again would deadlock [thread 0x55fd427bd048] Trying to unlock a mutex we don't own [thread 0x55fd427bd010] Finishing errorcheck mutex test [thread 0x55fd427bd048] Starting errorcheck mutex test [thread 0x55fd427bd048] Finishing errorcheck mutex test [thread 0x55fd427bd048] Trying to unlock unlocked mutex --- [thread main] Testing recursive mutex [thread main] Threads spawned successfully [thread main] Sleeping 7 seconds [thread 0x55fd427bd0f0] Trying to actuire the mutex succeeded [thread 0x55fd427bd0f0] Starting recursive mutex test [thread 0x55fd427bd0b8] Trying to actuire the mutex failed [thread 0x55fd427bd048] Trying to actuire the mutex failed [thread 0x55fd427bd010] Trying to actuire the mutex failed [thread 0x55fd427bd080] Trying to actuire the mutex failed [thread 0x55fd427bd0f0] Finishing recursive mutex test [thread 0x55fd427bd0b8] Starting recursive mutex test [thread 0x55fd427bd0b8] Finishing recursive mutex test [thread 0x55fd427bd048] Starting recursive mutex test [thread 0x55fd427bd048] Finishing recursive mutex test [thread 0x55fd427bd010] Starting recursive mutex test [thread 0x55fd427bd010] Finishing recursive mutex test [thread 0x55fd427bd080] Starting recursive mutex test [thread 0x55fd427bd080] Finishing recursive mutex test ``` 請補完程式碼,使其符合預期。作答規範: * `AAAA`, `BBBB`, `CCCC` 都是表示方式,且都該使用 `atomic_bool_cmpxchg` 巨集 * `DDDD` 為整數 :::success 延伸問題: 1. 解釋上述程式碼運作原理,指出其中缺失並改進 2. 實作 PRIO_INHERIT / PRIO_PROTECT mutexes :::