linux2020
目的: 檢驗學員對 timerfd 系統呼叫的認知
1
考慮以下 GNU/Linux 程式,假設裡頭每個系統呼叫都可順利執行:
#include <stdio.h>
#include <stdlib.h>
#include <sys/epoll.h>
#include <sys/timerfd.h>
#include <unistd.h>
struct posix_timer {
int tfd;
struct itimerspec ts;
timer_t timer;
};
static int efd;
static struct epoll_event ev;
static void do_handle(struct posix_timer *pt)
{
int tfd = pt->tfd;
pt->ts.it_value.tv_sec = 1;
pt->ts.it_value.tv_nsec = 0;
pt->ts.it_interval.tv_sec = 0;
pt->ts.it_interval.tv_nsec = 0;
timerfd_settime(tfd, 0, &pt->ts, NULL);
}
static void start_epoll(int fd, void *data)
{
efd = epoll_create(1);
struct epoll_event ev = {.events = EPOLLIN, .data.ptr = data};
if (epoll_ctl(efd, EPOLL_CTL_ADD, fd, &ev) == -1) {
perror("epoll_ctl");
exit(1);
}
while (1) {
printf("start to epoll wait...\n");
struct epoll_event events;
int ret = epoll_wait(efd, &events, 1, -1);
if (ret < 0) {
perror("epoll_wait");
exit(1);
}
printf("read...\n");
struct posix_timer *pt = events.data.ptr;
/* events is overwritten by epoll_wait, and have ev.data.fd */
int buf;
read(pt->tfd, &buf, sizeof(uint64_t));
printf("[%s] ret %d buf %d \n", __FUNCTION__, ret, buf);
do_handle(pt);
}
exit(1);
}
int main()
{
struct posix_timer pt = {.tfd = timerfd_create(CLOCK_REALTIME, 0)};
if (pt.tfd < 0) {
perror("timerfd_create");
exit(1);
}
pt.ts.it_value.tv_sec = AAA;
pt.ts.it_value.tv_nsec = 0;
pt.ts.it_interval.tv_sec = 0;
pt.ts.it_interval.tv_nsec = 0;
// run timer with rel-timer mode.
if (timerfd_settime(pt.tfd, 0, &pt.ts, NULL)) {
perror("timerfd_settime");
exit(1);
}
if (BBB) start_epoll(pt.tfd, &pt);
while (1) {
puts(".");
sleep(3);
}
return 0;
}
並且 $ cat /proc/sys/kernel/sched_child_runs_first
的輸出為 0
,該程式執行結果如下:
.
start to epoll wait...
.
read...
[start_epoll] ret 0 buf 1
start to epoll wait...
read...
[start_epoll] ret 0 buf 1
start to epoll wait...
.
read...
[start_epoll] ret 0 buf 1
start to epoll wait...
read...
[start_epoll] ret 0 buf 1
start to epoll wait...
read...
[start_epoll] ret 0 buf 1
start to epoll wait...
.
read...
[start_epoll] ret 0 buf 1
start to epoll wait...
read...
[start_epoll] ret 0 buf 1
start to epoll wait...
read...
[start_epoll] ret 0 buf 1
start to epoll wait...
.
read...
[start_epoll] ret 0 buf 1
start to epoll wait...
read...
[start_epoll] ret 0 buf 1
start to epoll wait...
read...
[start_epoll] ret 0 buf 1
start to epoll wait...
(後略)
請補完程式碼,使得輸出符合預期。
作答區
AAA = ?
(a)
0(b)
1(c)
5(d)
10(e)
15BBB = ?
(a)
fork()
(b)
!fork()
(c)
1
回歸第一手資料,透過反思 C 語言程式設計的細節,重新學習電腦原理
Jul 21, 2025自 Linux 核心原始程式碼編譯出 User-mode Linux 並運用工具來建構實驗所需的檔案系統
Jul 20, 2025系統的 throughput 是評斷排程器優劣的重要效能
Jul 19, 2025無論是作業系統核心、C 語言函式庫內部、程式開發框架,到應用程式,都不難見到 linked list 的身影,包含多種針對效能和安全議題所做的 linked list 變形,又還要考慮到應用程式的泛用性 (generic programming),是很好的進階題材。
Jul 17, 2025or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up