Try   HackMD

2020q1 第 15 週測驗題

tags: 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) 15

BBB = ?

  • (a) fork()
  • (b) !fork()
  • (c) 1