linux2022
目的: 檢驗學員對 並行和多執行緒程式設計 的認知
作答表單:
1
考慮到一個 lock-free 的軟體計時器實作,測試程式如下:
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include "lf_timer.h"
#define EX_HASHSTR(s) #s
#define EX_STR(s) EX_HASHSTR(s)
#define EXPECT(exp) \
do { \
if (!(exp)) \
fprintf(stderr, "FAILURE @ %s:%u; %s\n", __FILE__, __LINE__, \
EX_STR(exp)), \
abort(); \
} while (0)
static void callback(lf_timer_t tim, lf_tick_t tmo, void *arg)
{
lf_tick_t tck = lf_timer_tick_get();
printf("Timer %d expiration %#" PRIx64 " now %#" PRIx64 "\n", tim, tmo,
tck);
*(lf_tick_t *) arg = tck;
}
int main(void)
{
lf_tick_t exp_a = LF_TIMER_TICK_INVALID;
lf_timer_t tim_a = lf_timer_alloc(callback, &exp_a);
EXPECT(tim_a != LF_TIMER_NULL);
EXPECT(lf_timer_set(tim_a, 1));
EXPECT(!lf_timer_set(tim_a, 1));
lf_timer_tick_set(0);
lf_timer_expire();
EXPECT(exp_a == LF_TIMER_TICK_INVALID);
lf_timer_tick_set(1);
lf_timer_expire();
EXPECT(exp_a == 1);
EXPECT(lf_timer_set(tim_a, 2));
EXPECT(lf_timer_reset(tim_a, 3));
lf_timer_tick_set(2);
lf_timer_expire();
EXPECT(exp_a == 1);
EXPECT(lf_timer_cancel(tim_a));
lf_timer_tick_set(3);
lf_timer_expire();
EXPECT(exp_a == 1);
EXPECT(!lf_timer_reset(tim_a, UINT64_C(0xFFFFFFFFFFFFFFFE)));
EXPECT(lf_timer_set(tim_a, UINT64_C(0xFFFFFFFFFFFFFFFE)));
EXPECT(lf_timer_reset(tim_a, UINT64_C(0xFFFFFFFFFFFFFFFE)));
lf_timer_expire();
EXPECT(exp_a == 1);
lf_timer_tick_set(UINT64_C(0xFFFFFFFFFFFFFFFE));
lf_timer_expire();
EXPECT(exp_a == UINT64_C(0xFFFFFFFFFFFFFFFE));
lf_timer_free(tim_a);
printf("timer tests complete\n");
return 0;
}
預期執行輸出:
Timer 0 expiration 0x1 now 0x1
Timer 0 expiration 0xfffffffffffffffe now 0xfffffffffffffffe
timer tests complete
程式碼可參見 lf_timer,使用 C11 搭配 GNU extension。
請補完程式碼,使其運作符合預期。作答規範:
COND
為表示式FF1
和 FF2
為表示式延伸問題:
2
考慮到支援多個生產者—多個消費者的 bounded buffer lockfree 實作: gist (部分程式碼隱蔽)
程式碼使用 C11 Atomics 和 Threads 撰寫,預期執行輸出:
Test: Spsc: null_pointers : PASS
Test: Spsc: create : PASS
Test: Spsc: empty : PASS
Test: Spsc: full : PASS
Test: Spsc: sums10000 : PASS
Test: Mpsc: null_pointers : PASS
Test: Mpsc: create : PASS
Test: Mpsc: empty : PASS
Test: Mpsc: full : PASS
Test: Mpsc: sums10000 : PASS
Test: Spmc: null_pointers : PASS
Test: Spmc: create : PASS
Test: Spmc: empty : PASS
Test: Spmc: full : PASS
Test: Spmc: sums10000 : PASS
Test: Mpmc: null_pointers : PASS
Test: Mpmc: create : PASS
Test: Mpmc: empty : PASS
Test: Mpmc: full : PASS
Test: Mpmc: sums10000 : PASS
請補完程式碼,使其執行符合預期。作答規範:
MMM
是表示式,依據指定程式碼風格撰寫,以最精簡的形式Linux 核心對於 UNIX Process (繁體中文翻譯為「行程」,簡體翻譯為「進程」) 的實作相當複雜,不僅蘊含歷史意義 (幾乎每個欄位都值得講古),更是反映出資訊科技產業的變遷,核心程式碼的 task_struct 結構體更是一絕,廣泛涵蓋 process 狀態、處理器、檔案系統、signal 處理、底層追蹤機制等等資訊,更甚者,還很曖昧地保存著 thread (繁體中文翻譯為「執行緒」,簡體中文翻譯為「線程」) 的必要欄位,好似這兩者天生就脫不了干係。 本講座期望帶著聽眾得知 Linux 核心設計的特有思維,像是如何透過 LWP 和 NPTL 實作執行緒,又如何透過行程建立記憶體管理的一種抽象層,再者回顧行程間的 context switch 及排程機制,搭配 signal 處理 (千萬不要小看 kill,裡頭可是大有玄機!)。聽眾應可不至於迷失在茫茫程式碼大海中。
Aug 17, 2025「指標」扮演「記憶體」和「物件」之間的橋樑
Aug 16, 2025千萬不要小看數值系統,史上不少知名 軟體缺失案例 就因為開發者未能充分掌握相關議題,而釀成莫大的傷害與損失。
Aug 15, 2025無論是作業系統核心、C 語言函式庫內部、程式開發框架,到應用程式,都不難見到 linked list 的身影,包含多種針對效能和安全議題所做的 linked list 變形,又還要考慮到應用程式的泛用性 (generic programming),是很好的進階題材。
Aug 15, 2025or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up