เจเจพเจฃ เจชเจเจพเจฃ
เจเจธ เจฒเฉเจ เจตเจฟเฉฑเจ, เจ เจธเฉเจ เจเฉฑเจ I/O เจฐเจฟเจเจเจเจฐ เจฆเฉ เจ เฉฐเจฆเจฐ เจ เจคเฉ เจฌเจพเจนเจฐ เจฆเฉเจเจพเจเจเฉ เจ เจคเฉ เจเจน เจเจฟเจตเฉเจ เจเฉฐเจฎ เจเจฐเจฆเจพ เจนเฉ, เจเฉเจก เจฆเฉเจเจ 200 เจคเฉเจ เจเฉฑเจ เจฒเจพเจเจจเจพเจ เจตเจฟเฉฑเจ เจเฉฑเจ เจฒเจพเจเฉเจเจฐเจจ เจฒเจฟเจเจพเจเจเฉ, เจ เจคเฉ 40 เจฎเจฟเจฒเฉเจ เจจ เจฌเฉเจจเจคเฉเจเจ/เจฎเจฟเฉฐเจ เจคเฉเจ เจตเฉฑเจง เจเฉฑเจ เจธเจงเจพเจฐเจจ HTTP เจธเจฐเจตเจฐ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจฌเจฃเจพเจตเจพเจเจเฉเฅค
เจฎเฉเจเจฌเฉฐเจง
- เจฒเฉเจ I/O เจฐเจฟเจเจเจเจฐ เจฆเฉ เจเฉฐเจฎเจเจพเจ เจจเฉเฉฐ เจธเจฎเจเจฃ เจตเจฟเฉฑเจ เจฎเจฆเจฆ เจเจฐเจจ เจฒเจ เจฒเจฟเจเจฟเจ เจเจฟเจ เจธเฉ, เจ เจคเฉ เจเจธเจฒเจ เจเจธเจฆเฉ เจตเจฐเจคเฉเจ เจเจฐเจฆเฉ เจธเจฎเฉเจ เจเฉเจเจฎเจพเจ เจจเฉเฉฐ เจธเจฎเจเฉเฅค
- เจฒเฉเจ เจจเฉเฉฐ เจธเจฎเจเจฃ เจฒเจ เจฌเฉเจจเจฟเจเจฆเฉ เจเจฟเจเจจ เจฆเฉ เจฒเฉเฉ เจนเฉเฅค
เจธเฉ เจญเจพเจธเจผเจพ เจ เจคเฉ เจจเฉเฉฑเจเจตเจฐเจ เจเจชเจฒเฉเจเฉเจธเจผเจจ เจกเจฟเจตเฉเจฒเจชเจฎเฉเจเจ เจตเจฟเฉฑเจ เจเฉเจ เจ เจจเฉเจญเจตเฅค - เจธเจพเจฐเฉ เจเฉเจก เจจเฉเฉฐ (เจธเจพเจตเจงเจพเจจ: เจฒเฉฐเจฌเฉ PDF)
C11 เจธเจเฉเจเจกเจฐเจก เจคเฉฑเจ Linux เจฒเจ เจ เจคเฉ เจเจธ 'เจคเฉ เจเจชเจฒเจฌเจง เจนเฉGitHub .
เจเจน เจเจฟเจเจ เจเจผเจฐเฉเจฐเฉ เจนเฉ?
เจเฉฐเจเจฐเจจเฉเฉฑเจ เจฆเฉ เจตเจงเจฆเฉ เจชเฉเจฐเจธเจฟเฉฑเจงเฉ เจฆเฉ เจจเจพเจฒ, เจตเฉเฉฑเจฌ เจธเจฐเจตเจฐเจพเจ เจจเฉเฉฐ เจเฉฑเจเฉ เจธเจฎเฉเจ เจตเฉฑเจกเฉ เจเจฟเจฃเจคเฉ เจตเจฟเฉฑเจ เจเฉเจจเฉเจเจธเจผเจจเจพเจ เจจเฉเฉฐ เจธเฉฐเจญเจพเจฒเจฃ เจฆเฉ เจฒเฉเฉ เจชเฉเจฃ เจฒเฉฑเจเฉ, เจ
เจคเฉ เจเจธ เจฒเจ เจฆเฉ เจคเจฐเฉเจเฉ เจ
เจเจผเจฎเจพเจเจฃเฉ เจชเจ: เจตเฉฑเจกเฉ เจเจฟเจฃเจคเฉ เจตเจฟเฉฑเจ OS เจฅเจฐเจฟเฉฑเจกเจพเจ 'เจคเฉ I/O เจจเฉเฉฐ เจฌเจฒเจพเจ เจเจฐเจจเจพ เจ
เจคเฉ I/O เจจเฉเฉฐ เจจเจพ-เจฌเจฒเจพเจ เจเจฐเจจเจพเฅค เจเฉฑเจ เจเจตเฉเจเจ เจจเฉเจเฉเจซเจฟเจเฉเจธเจผเจจ เจธเจฟเจธเจเจฎ, เจเจฟเจธเจจเฉเฉฐ "เจธเจฟเจธเจเจฎ เจเฉเจฃเจเจพเจฐ" เจตเฉ เจเจฟเจนเจพ เจเจพเจเจฆเจพ เจนเฉ (
เจชเจนเจฟเจฒเฉ เจชเจนเฉเฉฐเจ เจตเจฟเฉฑเจ เจนเจฐเฉเจ เจเจเจฃ เจตเจพเจฒเฉ เจเฉเจจเฉเจเจธเจผเจจ เจฒเจ เจเฉฑเจ เจจเจตเจพเจ OS เจฅเฉเจฐเฉเจก เจฌเจฃเจพเจเจฃเจพ เจธเจผเจพเจฎเจฒ เจนเฉเฅค เจเจธเจฆเจพ เจจเฉเจเจธเจพเจจ เจฎเจพเฉเฉ เจฎเจพเจชเจฏเฉเจเจคเจพ เจนเฉ: เจเจชเจฐเฉเจเจฟเฉฐเจ เจธเจฟเจธเจเจฎ เจจเฉเฉฐ เจฌเจนเฉเจค เจธเจพเจฐเฉ เจฒเจพเจเฉ เจเจฐเจจเฉ เจชเฉเจฃเจเฉ
เจธเฉเจงเจฟเจ เจนเฉเจเจ เจธเฉฐเจธเจเจฐเจฃ เจนเจพเจเจฒเจพเจเจ เจเจฐเจฆเจพ เจนเฉ
เจฆเฉเจเฉ เจชเจนเฉเฉฐเจ เจตเจฐเจคเจฆเจพ เจนเฉ
เจเจนเจจเจพเจ เจชเจนเฉเฉฐเจเจพเจ เจตเจฟเฉฑเจ เจ เฉฐเจคเจฐ เจเจธ เจชเฉเจฐเจเจพเจฐ เจนเฉ:
- I/O เจเจชเจฐเฉเจธเจผเจจเจพเจ เจจเฉเฉฐ เจฌเจฒเฉเจ เจเจฐเจจเจพ เจฎเฉเจ
เฉฑเจคเจฒ เจเจชเจญเฉเจเจคเจพ เจตเจนเจพเจ
เจเจฆ เจคเฉฑเจเจเจเจธ เจ เฉเจ เจนเฉเจฃ เจคเฉฑเจ
เจกเฉเจซเฉเจฐเฉเจเจฎเฉเจเจเจธ เจเจเจฃ เจตเจพเจฒเจพIP เจชเฉเจเฉเจ เจฌเจพเจเจ เจธเจเฉเจฐเฉเจฎ เจจเฉเฉฐ (TCP , เจกเจพเจเจพ เจชเฉเจฐเจพเจชเจค เจเจฐเจจเจพ) เจเจพเจ เจ เฉฐเจฆเจฐเฉเจจเฉ เจฐเจพเจเจ เจฌเจซเจฐเจพเจ เจตเจฟเฉฑเจ เจฌเจพเจ เจฆ เจตเจฟเฉฑเจ เจญเฉเจเจฃ เจฒเจ เจฒเฉเฉเฉเจเจฆเฉ เจฅเจพเจ เจเจชเจฒเจฌเจง เจจเจนเฉเจ เจนเฉเจตเฉเจเฉเจเจจ เจเจ เจธเฉ (เจกเฉเจเจพ เจญเฉเจเจฃเจพ) - เจธเจฟเจธเจเจฎ เจเฉเจฃเจเจพเจฐ afikun asiko เจชเฉเจฐเฉเจเจฐเจพเจฎ เจจเฉเฉฐ เจธเฉเจเจฟเจค เจเจฐเจฆเจพ เจนเฉ เจเจฟ เจ.เจเจธ เจนเฉ เจกเฉเจซเฉเจฐเฉเจเจฎเฉเจเจ เจเฉเจคเฉ IP เจชเฉเจเฉเจ (TCP, เจกเฉเจเจพ เจฐเจฟเจธเฉเจชเจธเจผเจจ) เจเจพเจ เจ เฉฐเจฆเจฐเฉเจจเฉ เจฐเจพเจเจ เจฌเจซเจฐเจพเจ เจตเจฟเฉฑเจ เจเจพเจซเจผเฉ เจฅเจพเจ เจนเฉ เจเจชเจฒเจฌเจง (เจกเฉเจเจพ เจญเฉเจเจฃเจพ).
เจเจธ เจจเฉเฉฐ เจธเฉฐเจเฉเจช เจเจฐเจจ เจฒเจ, เจนเจฐเฉเจ I/O เจฒเจ เจเฉฑเจ OS เจฅเฉเจฐเฉเจก เจฐเจฟเจเจผเจฐเจต เจเจฐเจจเจพ เจเฉฐเจชเจฟเจเจเจฟเฉฐเจ เจชเจพเจตเจฐ เจฆเฉ เจฌเจฐเจฌเจพเจฆเฉ เจนเฉ, เจเจฟเจเจเจเจฟ เจ
เจธเจฒ เจตเจฟเฉฑเจ, เจฅเฉเจฐเฉเจก เจเจชเจฏเฉเจเฉ เจเฉฐเจฎ เจจเจนเฉเจ เจเจฐ เจฐเจนเฉ เจนเจจ (เจเจธ เจฒเจ เจเจน เจธเจผเจฌเจฆ
I/O เจฐเจฟเจเจเจเจฐ เจฎเจพเจกเจฒ
I/O เจฐเจฟเจเจเจเจฐ เจธเจฟเจธเจเจฎ เจเฉเจฃเจเจพเจฐ เจ เจคเฉ เจเจชเจญเฉเจเจคเจพ เจเฉเจก เจฆเฉ เจตเจฟเจเจเจพเจฐ เจเฉฑเจ เจชเจฐเจค เจตเจเฉเจ เจเฉฐเจฎ เจเจฐเจฆเจพ เจนเฉเฅค เจเจธเจฆเฉ เจธเฉฐเจเจพเจฒเจจ เจฆเฉ เจธเจฟเจงเจพเจเจค เจจเฉเฉฐ เจนเฉเจ เจพเจ เจฆเจฟเฉฑเจคเฉ เจฌเจฒเจพเจ เจเจฟเฉฑเจคเจฐ เจฆเฉเจเจฐเจพ เจฆเจฐเจธเจพเจเจ เจเจฟเจ เจนเฉ:
- เจฎเฉเจจเฉเฉฐ เจคเฉเจนเจพเจจเฉเฉฐ เจฏเจพเจฆ เจฆเจฟเจตเจพเจเจฃ เจฆเจฟเจ เจเจฟ เจเฉฑเจ เจเจตเฉเจเจ เจเฉฑเจ เจจเฉเจเฉเจซเจฟเจเฉเจธเจผเจจ เจนเฉ เจเฉ เจเฉฑเจ เจเจพเจธ เจธเจพเจเจ เจเฉฑเจ เจเฉเจฐ-เจฌเจฒเจพเจเจฟเฉฐเจ I/O เจเจพเจฐเจตเจพเจ เจเจฐเจจ เจฆเฉ เจฏเฉเจ เจนเฉเฅค
- เจเฉฑเจ เจเจตเฉเจเจ เจนเฉเจเจกเจฒเจฐ เจเฉฑเจ เจซเฉฐเจเจธเจผเจจ เจนเฉเฉฐเจฆเจพ เจนเฉ เจเจฟเจธเจจเฉเฉฐ I/O เจฐเจฟเจเจเจเจฐ เจฆเฉเจเจฐเจพ เจฌเฉเจฒเจพเจเจ เจเจพเจเจฆเจพ เจนเฉ เจเจฆเฉเจ เจเฉฑเจ เจเจตเฉเจเจ เจชเฉเจฐเจพเจชเจค เจนเฉเฉฐเจฆเจพ เจนเฉ, เจเฉ เจซเจฟเจฐ เจเฉฑเจ เจเฉเจฐ-เจฌเจฒเจพเจเจฟเฉฐเจ I/O เจเจพเจฐเจตเจพเจ เจเจฐเจฆเจพ เจนเฉเฅค
เจเจน เจจเฉเจ เจเจฐเจจเจพ เจฎเจนเฉฑเจคเจตเจชเฉเจฐเจจ เจนเฉ เจเจฟ I/O เจฐเจฟเจเจเจเจฐ เจชเจฐเจฟเจญเจพเจธเจผเจพ เจ เจจเฉเจธเจพเจฐ เจธเจฟเฉฐเจเจฒ-เจฅเฉเจฐเฉเฉฑเจกเจก เจนเฉ, เจชเจฐ 1 เจฅเฉเจฐเฉเจก: 1 เจฐเจฟเจเจเจเจฐ เจฆเฉ เจ เจจเฉเจชเจพเจค 'เจคเฉ เจฎเจฒเจเฉ-เจฅเฉเจฐเฉเจกเจก เจตเจพเจคเจพเจตเจฐเจจ เจตเจฟเฉฑเจ เจตเจฐเจคเจฃ เจคเฉเจ เจธเฉฐเจเจฒเจช เจจเฉเฉฐ เจเฉเจ เจตเฉ เจจเจนเฉเจ เจฐเฉเจ เจฐเจฟเจนเจพ เจนเฉ, เจเจฟเจธ เจจเจพเจฒ เจธเจพเจฐเฉ CPU เจเฉเจฐเจพเจ เจจเฉเฉฐ เจฐเฉเจธเจพเจเจเจฒ เจเฉเจคเจพ เจเจพเจตเฉเจเจพเฅค
ะ ะตะฐะปะธะทะฐัะธั
เจ
เจธเฉเจ เจชเจฌเจฒเจฟเจ เจเฉฐเจเจฐเจซเฉเจธ เจจเฉเฉฐ เจเฉฑเจ เจซเจพเจเจฒ เจตเจฟเฉฑเจ เจฐเฉฑเจเจพเจเจเฉ reactor.h
reactor.c
reactor.h
เจนเฉเจ เจฒเจฟเจเฉเจเจ เจเฉเจธเจผเจฃเจพเจตเจพเจ เจธเจผเจพเจฎเจฒ เจนเฉเจฃเจเฉเจเจ:
reactor.h เจตเจฟเฉฑเจ เจเฉเจธเจผเจฃเจพเจตเจพเจ เจฆเจฟเจเจพเจ
typedef struct reactor Reactor;
/*
* ะฃะบะฐะทะฐัะตะปั ะฝะฐ ััะฝะบัะธั, ะบะพัะพัะฐั ะฑัะดะตั ะฒัะทัะฒะฐัััั I/O ัะตะฐะบัะพัะพะผ ะฟัะธ ะฟะพัััะฟะปะตะฝะธะธ
* ัะพะฑััะธั ะพั ัะธััะตะผะฝะพะณะพ ัะตะปะตะบัะพัะฐ.
*/
typedef void (*Callback)(void *arg, int fd, uint32_t events);
/*
* ะะพะทะฒัะฐัะฐะตั `NULL` ะฒ ัะปััะฐะต ะพัะธะฑะบะธ, ะฝะต-`NULL` ัะบะฐะทะฐัะตะปั ะฝะฐ `Reactor` ะฒ
* ะฟัะพัะธะฒะฝะพะผ ัะปััะฐะต.
*/
Reactor *reactor_new(void);
/*
* ะัะฒะพะฑะพะถะดะฐะตั ัะธััะตะผะฝัะน ัะตะปะตะบัะพั, ะฒัะต ะทะฐัะตะณะธัััะธัะพะฒะฐะฝะฝัะต ัะพะบะตัั ะฒ ะดะฐะฝะฝัะน ะผะพะผะตะฝั
* ะฒัะตะผะตะฝะธ ะธ ัะฐะผ I/O ัะตะฐะบัะพั.
*
* ะกะปะตะดัััะธะต ััะฝะบัะธะธ ะฒะพะทะฒัะฐัะฐัั -1 ะฒ ัะปััะฐะต ะพัะธะฑะบะธ, 0 ะฒ ัะปััะฐะต ััะฟะตั
ะฐ.
*/
int reactor_destroy(Reactor *reactor);
int reactor_register(const Reactor *reactor, int fd, uint32_t interest,
Callback callback, void *callback_arg);
int reactor_deregister(const Reactor *reactor, int fd);
int reactor_reregister(const Reactor *reactor, int fd, uint32_t interest,
Callback callback, void *callback_arg);
/*
* ะะฐะฟััะบะฐะตั ัะธะบะป ัะพะฑััะธะน ั ัะฐะนะผ-ะฐััะพะผ `timeout`.
*
* ะญัะฐ ััะฝะบัะธั ะฟะตัะตะดะฐัั ัะฟัะฐะฒะปะตะฝะธะต ะฒัะทัะฒะฐััะตะผั ะบะพะดั ะตัะปะธ ะพัะฒะตะดัะฝะฝะพะต ะฒัะตะผั ะฒััะปะพ
* ะธะปะธ/ะธ ะฟัะธ ะพััััััะฒะธะธ ะทะฐัะตะณะธัััะธัะพะฒะฐะฝะฝัั
ัะพะบะตัะพะฒ.
*/
int reactor_run(const Reactor *reactor, time_t timeout);
I/O เจฐเจฟเจเจเจเจฐ เจฌเจฃเจคเจฐ เจฆเฉ เจธเจผเจพเจฎเจฒ เจนเจจ GHashTable
CallbackData
(เจเฉฑเจ เจเจตเฉเจเจ เจนเฉเจเจกเจฒเจฐ เจฆเจพ เจขเจพเจเจเจพ เจ
เจคเฉ เจเจธเจฆเฉ เจฒเจ เจเฉฑเจ เจเจชเจญเฉเจเจคเจพ เจฆเจฒเฉเจฒ)เฅค
เจฐเจฟเจเจเจเจฐ เจ เจคเฉ เจเจพเจฒเจฌเฉเจเจกเจพเจเจพ เจฆเจฟเจเจพเจ
struct reactor {
int epoll_fd;
GHashTable *table; // (int, CallbackData)
};
typedef struct {
Callback callback;
void *arg;
} CallbackData;
เจเจฟเจฐเจชเจพ เจเจฐเจเฉ เจงเจฟเจเจจ เจฆเจฟเจ เจเจฟ เจ
เจธเฉเจ เจนเฉเจเจกเจฒ เจเจฐเจจ เจฆเฉ เจธเจฎเจฐเฉฑเจฅเจพ เจจเฉเฉฐ เจธเจฎเจฐเฉฑเจฅ เจฌเจฃเจพเจเจ เจนเฉ reactor.h
เจ
เจธเฉเจ เจขเจพเจเจเฉ เจฆเจพ เจเจฒเจพเจจ เจเจฐเจฆเฉ เจนเจพเจ reactor
เจ
เจคเฉ เจ
เฉฐเจฆเจฐ reactor.c
เจ
เจธเฉเจ เจเจธเจจเฉเฉฐ เจชเจฐเจฟเจญเจพเจธเจผเจฟเจค เจเจฐเจฆเฉ เจนเจพเจ, เจเจธ เจคเจฐเฉเจนเจพเจ เจเจชเจญเฉเจเจคเจพ เจจเฉเฉฐ เจเจธเจฆเฉ เจเฉเจคเจฐเจพเจ เจจเฉเฉฐ เจธเจชเจธเจผเจ เจฐเฉเจช เจตเจฟเฉฑเจ เจฌเจฆเจฒเจฃ เจคเฉเจ เจฐเฉเจเจฆเจพ เจนเฉเฅค เจเจน เจชเฉเจเจฐเจจ เจฆเฉ เจเฉฑเจ เจนเฉ
เจซเฉฐเจเจธเจผเจจ reactor_register
, reactor_deregister
ะธ reactor_reregister
เจธเจฟเจธเจเจฎ เจเฉเจฃเจเจพเจฐ เจ
เจคเฉ เจนเฉเจธเจผ เจเฉเจฌเจฒ เจตเจฟเฉฑเจ เจฆเจฟเจฒเจเจธเจชเฉ เจฆเฉเจเจ เจธเจพเจเจเจพเจ เจ
เจคเฉ เจธเฉฐเจฌเฉฐเจงเจฟเจค เจเจตเฉเจเจ เจนเฉเจเจกเจฒเจฐ เจฆเฉ เจธเฉเจเฉ เจจเฉเฉฐ เจ
เฉฑเจชเจกเฉเจ เจเจฐเฉเฅค
เจฐเจเจฟเจธเจเฉเจฐเฉเจธเจผเจจ เจซเฉฐเจเจธเจผเจจ เจฆเจฟเจเจพเจ
#define REACTOR_CTL(reactor, op, fd, interest)
if (epoll_ctl(reactor->epoll_fd, op, fd,
&(struct epoll_event){.events = interest,
.data = {.fd = fd}}) == -1) {
perror("epoll_ctl");
return -1;
}
int reactor_register(const Reactor *reactor, int fd, uint32_t interest,
Callback callback, void *callback_arg) {
REACTOR_CTL(reactor, EPOLL_CTL_ADD, fd, interest)
g_hash_table_insert(reactor->table, int_in_heap(fd),
callback_data_new(callback, callback_arg));
return 0;
}
int reactor_deregister(const Reactor *reactor, int fd) {
REACTOR_CTL(reactor, EPOLL_CTL_DEL, fd, 0)
g_hash_table_remove(reactor->table, &fd);
return 0;
}
int reactor_reregister(const Reactor *reactor, int fd, uint32_t interest,
Callback callback, void *callback_arg) {
REACTOR_CTL(reactor, EPOLL_CTL_MOD, fd, interest)
g_hash_table_insert(reactor->table, int_in_heap(fd),
callback_data_new(callback, callback_arg));
return 0;
}
I/O เจฐเจฟเจเจเจเจฐ เจจเฉ เจตเจฐเจฃเจจเจเจฐเจคเจพ เจจเจพเจฒ เจเจเจจเจพ เจจเฉเฉฐ เจฐเฉเจเจฟเจ เจนเฉ fd
, เจเจน เจธเฉฐเจฌเฉฐเจงเจฟเจค เจเจตเฉเจเจ เจนเฉเจเจกเจฒเจฐ เจจเฉเฉฐ เจเจพเจฒ เจเจฐเจฆเจพ เจนเฉ, เจเจฟเจธ เจคเฉฑเจ เจเจน เจชเจพเจธ เจนเฉเฉฐเจฆเจพ เจนเฉ fd
, void
.
reactor_run() เจซเฉฐเจเจธเจผเจจ เจฆเจฟเจเจพเจ
int reactor_run(const Reactor *reactor, time_t timeout) {
int result;
struct epoll_event *events;
if ((events = calloc(MAX_EVENTS, sizeof(*events))) == NULL)
abort();
time_t start = time(NULL);
while (true) {
time_t passed = time(NULL) - start;
int nfds =
epoll_wait(reactor->epoll_fd, events, MAX_EVENTS, timeout - passed);
switch (nfds) {
// ะัะธะฑะบะฐ
case -1:
perror("epoll_wait");
result = -1;
goto cleanup;
// ะัะตะผั ะฒััะปะพ
case 0:
result = 0;
goto cleanup;
// ะฃัะฟะตัะฝะฐั ะพะฟะตัะฐัะธั
default:
// ะัะทะฒะฐัั ะพะฑัะฐะฑะพััะธะบะพะฒ ัะพะฑััะธะน
for (int i = 0; i < nfds; i++) {
int fd = events[i].data.fd;
CallbackData *callback =
g_hash_table_lookup(reactor->table, &fd);
callback->callback(callback->arg, fd, events[i].events);
}
}
}
cleanup:
free(events);
return result;
}
เจธเฉฐเจเฉเจช เจเจฐเจจ เจฒเจ, เจเจชเจญเฉเจเจคเจพ เจเฉเจก เจตเจฟเฉฑเจ เจซเฉฐเจเจธเจผเจจ เจเจพเจฒเจพเจ เจฆเฉ เจฒเฉเฉ เจนเฉเจ เจฒเจฟเจเฉ เจฐเฉเจช เจตเจฟเฉฑเจ เจนเฉเจตเฉเจเฉ:
เจธเจฟเฉฐเจเจฒ เจฅเจฐเจฟเฉฑเจกเจก เจธเจฐเจตเจฐ
เจเฉฑเจ เจฒเฉเจก เจฆเฉ เจ เจงเฉเจจ I/O เจฐเจฟเจเจเจเจฐ เจฆเฉ เจเจพเจเจ เจเจฐเจจ เจฒเจ, เจ เจธเฉเจ เจเฉฑเจ เจธเจงเจพเจฐเจจ HTTP เจตเฉเจฌ เจธเจฐเจตเจฐ เจฒเจฟเจเจพเจเจเฉ เจเฉ เจเฉฑเจ เจเจฟเฉฑเจคเจฐ เจฆเฉ เจจเจพเจฒ เจเจฟเจธเฉ เจตเฉ เจฌเฉเจจเจคเฉ เจฆเจพ เจเจตเจพเจฌ เจฆเจฟเฉฐเจฆเจพ เจนเฉเฅค
HTTP เจชเฉเจฐเฉเจเฉเจเฉเจฒ เจฆเจพ เจเฉฑเจ เจคเฉเจเจผ เจนเจตเจพเจฒเจพ
HTTP เจจเฉเฉฐ เจเจธเจพเจจเฉ เจจเจพเจฒ เจตเจฐเจคเจฟเจ เจเจพ เจธเจเจฆเจพ เจนเฉ
เจฌเฉเจจเจคเฉ เจซเจพเจฐเจฎเฉเจ
<ะะะะะะะ> <URI> <ะะะ ะกะะฏ HTTP>CRLF
<ะะะะะะะะะ 1>CRLF
<ะะะะะะะะะ 2>CRLF
<ะะะะะะะะะ N>CRLF CRLF
<ะะะะะซะ>
CRLF
เจฆเฉ เจ เฉฑเจเจฐเจพเจ เจฆเจพ เจเฉเจฐเจฎ เจนเฉ:r
ะธn
, เจฌเฉเจจเจคเฉ เจฆเฉ เจชเจนเจฟเจฒเฉ เจฒเจพเจเจจ, เจธเจฟเจฐเจฒเฉเจ เจ เจคเฉ เจกเฉเจเจพ เจจเฉเฉฐ เจตเฉฑเจ เจเจฐเจจเจพเฅค<ะะะะะะะ>
- เจตเจฟเจเฉ เจเจCONNECT
,DELETE
,GET
,HEAD
,OPTIONS
,PATCH
,POST
,PUT
,TRACE
. เจฌเฉเจฐเจพเจเจเจผเจฐ เจธเจพเจกเฉ เจธเจฐเจตเจฐ เจจเฉเฉฐ เจเฉฑเจ เจเจฎเจพเจเจก เจญเฉเจเฉเจเจพGET
, เจฎเจคเจฒเจฌ "เจฎเฉเจจเฉเฉฐ เจซเจพเจเจฒ เจฆเฉ เจธเจฎเฉฑเจเจฐเฉ เจญเฉเจเฉเฅค"<URI>
-เจเจเจธเจพเจฐ เจธเจฐเฉเจค เจชเจเจพเจฃเจเจฐเจคเจพ . เจเจฆเจพเจนเจฐเจจ เจฒเจ, เจเฉเจเจฐ URI =/index.html
, เจซเจฟเจฐ เจเจฒเจพเจเฉฐเจ เจธเจพเจเจ เจฆเฉ เจฎเฉเฉฑเจ เจชเฉฐเจจเฉ เจจเฉเฉฐ เจฌเฉเจจเจคเฉ เจเจฐเจฆเจพ เจนเฉเฅค<ะะะ ะกะะฏ HTTP>
โ เจซเจพเจฐเจฎเฉเจ เจตเจฟเฉฑเจ HTTP เจชเฉเจฐเฉเจเฉเจเฉเจฒ เจฆเจพ เจธเฉฐเจธเจเจฐเจฃHTTP/X.Y
. เจ เฉฑเจ เจธเจญ เจคเฉเจ เจตเฉฑเจง เจตเจฐเจคเจฟเจ เจเจพเจฃ เจตเจพเจฒเจพ เจธเฉฐเจธเจเจฐเจฃ เจนเฉHTTP/1.1
.<ะะะะะะะะะ N>
เจซเจพเจฐเจฎเฉเจ เจตเจฟเฉฑเจ เจเฉฑเจ เจฎเฉเฉฑเจ-เจฎเฉเฉฑเจฒ เจเฉเฉเจพ เจนเฉ<ะะะฎะง>: <ะะะะงะะะะ>
, เจนเฉเจฐ เจตเจฟเจธเจผเจฒเฉเจธเจผเจฃ เจฒเจ เจธเจฐเจตเจฐ เจจเฉเฉฐ เจญเฉเจเจฟเจ เจเจฟเจเฅค<ะะะะะซะ>
โ เจธเจฐเจตเจฐ เจฆเฉเจเจฐเจพ เจเจพเจฐเจตเจพเจ เจเจฐเจจ เจฒเจ เจฒเฉเฉเฉเจเจฆเจพ เจกเจพเจเจพเฅค เจ เจเจธเจฐ เจเจน เจธเจงเจพเจฐเจจ เจนเฉเฉฐเจฆเจพ เจนเฉJSON เจเจพเจ เจเฉเจ เจนเฉเจฐ เจซเจพเจฐเจฎเฉเจเฅค
เจเจตเจพเจฌ เจซเจพเจฐเจฎเฉเจ
<ะะะ ะกะะฏ HTTP> <ะะะ ะกะขะะขะฃะกะ> <ะะะะกะะะะ ะกะขะะขะฃะกะ>CRLF
<ะะะะะะะะะ 1>CRLF
<ะะะะะะะะะ 2>CRLF
<ะะะะะะะะะ N>CRLF CRLF
<ะะะะะซะ>
<ะะะ ะกะขะะขะฃะกะ>
เจเฉฑเจ เจธเฉฐเจเจฟเจ เจนเฉ เจเฉ เจเจพเจฐเจตเจพเจ เจฆเฉ เจจเจคเฉเจเฉ เจจเฉเฉฐ เจฆเจฐเจธเจพเจเจเจฆเฉ เจนเฉเฅค เจธเจพเจกเจพ เจธเจฐเจตเจฐ เจนเจฎเฉเจธเจผเจพ เจธเจฅเจฟเจคเฉ 200 (เจธเจซเจฒ เจเจพเจฐเจตเจพเจ) เจตเจพเจชเจธ เจเจฐเฉเจเจพเฅค<ะะะะกะะะะ ะกะขะะขะฃะกะ>
- เจธเจฅเจฟเจคเฉ เจเฉเจก เจฆเฉ เจธเจคเจฐ เจชเฉเจฐเจคเฉเจจเจฟเจงเจคเจพเฅค เจธเจเฉเจเจธ เจเฉเจก 200 เจฒเจ เจเจน เจนเฉOK
.<ะะะะะะะะะ N>
โ เจฌเฉเจจเจคเฉ เจฆเฉ เจฐเฉเจช เจตเจฟเฉฑเจ เจเจธเฉ เจซเจพเจฐเจฎเฉเจ เจฆเจพ เจธเจฟเจฐเจฒเฉเจเฅค เจ เจธเฉเจ เจเจผเจฟเจคเจพเจฌ เจตเจพเจชเจธ เจเจฐ เจฆเฉเจตเจพเจเจเฉContent-Length
(เจซเจพเจเจฒ เจฆเจพ เจเจเจพเจฐ) เจ เจคเฉContent-Type: text/html
(เจตเจพเจชเจธเฉ เจกเจพเจเจพ เจเจฟเจธเจฎ)เฅค<ะะะะะซะ>
โ เจเจชเจญเฉเจเจคเจพ เจฆเฉเจเจฐเจพ เจฌเฉเจจเจคเฉ เจเฉเจคเฉ เจเจ เจกเฉเจเจพเฅค เจธเจพเจกเฉ เจเฉเจธ เจตเจฟเฉฑเจ, เจเจน เจเจฟเฉฑเจคเจฐ เจฆเจพ เจฎเจพเจฐเจ เจนเฉHTML .
เจซเจพเจเจฒ http_server.c
common.h
Common.h เจตเจฟเฉฑเจ เจซเฉฐเจเจธเจผเจจ เจชเฉเจฐเฉเจเฉเจเจพเจเจช เจฆเจฟเจเจพเจ
/*
* ะะฑัะฐะฑะพััะธะบ ัะพะฑััะธะน, ะบะพัะพััะน ะฒัะทะพะฒะตััั ะฟะพัะปะต ัะพะณะพ, ะบะฐะบ ัะพะบะตั ะฑัะดะตั
* ะณะพัะพะฒ ะฟัะธะฝััั ะฝะพะฒะพะต ัะพะตะดะธะฝะตะฝะธะต.
*/
static void on_accept(void *arg, int fd, uint32_t events);
/*
* ะะฑัะฐะฑะพััะธะบ ัะพะฑััะธะน, ะบะพัะพััะน ะฒัะทะพะฒะตััั ะฟะพัะปะต ัะพะณะพ, ะบะฐะบ ัะพะบะตั ะฑัะดะตั
* ะณะพัะพะฒ ะพัะฟัะฐะฒะธัั HTTP ะพัะฒะตั.
*/
static void on_send(void *arg, int fd, uint32_t events);
/*
* ะะฑัะฐะฑะพััะธะบ ัะพะฑััะธะน, ะบะพัะพััะน ะฒัะทะพะฒะตััั ะฟะพัะปะต ัะพะณะพ, ะบะฐะบ ัะพะบะตั ะฑัะดะตั
* ะณะพัะพะฒ ะฟัะธะฝััั ัะฐััั HTTP ะทะฐะฟัะพัะฐ.
*/
static void on_recv(void *arg, int fd, uint32_t events);
/*
* ะะตัะตะฒะพะดะธั ะฒั
ะพะดััะตะต ัะพะตะดะธะฝะตะฝะธะต ะฒ ะฝะตะฑะปะพะบะธััััะธะน ัะตะถะธะผ.
*/
static void set_nonblocking(int fd);
/*
* ะะตัะฐัะฐะตั ะฟะตัะตะดะฐะฝะฝัะต ะฐัะณัะผะตะฝัั ะฒ stderr ะธ ะฒัั
ะพะดะธั ะธะท ะฟัะพัะตััะฐ ั
* ะบะพะดะพะผ `EXIT_FAILURE`.
*/
static noreturn void fail(const char *format, ...);
/*
* ะะพะทะฒัะฐัะฐะตั ัะฐะนะปะพะฒัะน ะดะตัะบัะธะฟัะพั ัะพะบะตัะฐ, ัะฟะพัะพะฑะฝะพะณะพ ะฟัะธะฝะธะผะฐัั ะฝะพะฒัะต
* TCP ัะพะตะดะธะฝะตะฝะธั.
*/
static int new_server(bool reuse_port);
เจซเฉฐเจเจธเจผเจจเจฒ เจฎเฉเจเจฐเฉ เจฆเจพ เจตเฉ เจตเจฐเจฃเจจ เจเฉเจคเจพ เจเจฟเจ เจนเฉ SAFE_CALL()
เจ
เจคเฉ เจซเฉฐเจเจธเจผเจจ เจชเจฐเจฟเจญเจพเจธเจผเจฟเจค เจเฉเจคเจพ เจเจฟเจ เจนเฉ fail()
. เจฎเฉเจเจฐเฉ เจธเจฎเฉเจเจฐเจจ เจฆเฉ เจฎเฉเฉฑเจฒ เจฆเฉ เจเจฒเจคเฉ เจจเจพเจฒ เจคเฉเจฒเจจเจพ เจเจฐเจฆเจพ เจนเฉ, เจ
เจคเฉ เจเฉเจเจฐ เจธเจฅเจฟเจคเฉ เจธเจนเฉ เจนเฉ, เจคเจพเจ เจซเฉฐเจเจธเจผเจจ เจจเฉเฉฐ เจเจพเจฒ เจเจฐเจฆเจพ เจนเฉ fail()
:
#define SAFE_CALL(call, error)
do {
if ((call) == error) {
fail("%s", #call);
}
} while (false)
เจซเฉฐเจเจธเจผเจจ fail()
เจชเจพเจธ เจเฉเจคเฉ เจเจฐเจเฉเจฎเฉเจเจเจพเจ เจจเฉเฉฐ เจเจฐเจฎเฉเจจเจฒ 'เจคเฉ เจชเฉเจฐเจฟเฉฐเจ เจเจฐเจฆเจพ เจนเฉ (เจเจฟเจตเฉเจ printf()
EXIT_FAILURE
:
static noreturn void fail(const char *format, ...) {
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
fprintf(stderr, ": %sn", strerror(errno));
exit(EXIT_FAILURE);
}
เจซเฉฐเจเจธเจผเจจ new_server()
เจธเจฟเจธเจเจฎ เจเจพเจฒเจพเจ เจฆเฉเจเจฐเจพ เจฌเจฃเจพเจ "เจธเจฐเจตเจฐ" เจธเจพเจเจ เจฆเจพ เจซเจพเจเจฒ เจกเจฟเจธเจเฉเจฐเจฟเจชเจเจฐ เจตเจพเจชเจธ เจเจฐเจฆเจพ เจนเฉ socket()
bind()
listen()
new_server() เจซเฉฐเจเจธเจผเจจ เจฆเจฟเจเจพเจ
static int new_server(bool reuse_port) {
int fd;
SAFE_CALL((fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP)),
-1);
if (reuse_port) {
SAFE_CALL(
setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &(int){1}, sizeof(int)),
-1);
}
struct sockaddr_in addr = {.sin_family = AF_INET,
.sin_port = htons(SERVER_PORT),
.sin_addr = {.s_addr = inet_addr(SERVER_IPV4)},
.sin_zero = {0}};
SAFE_CALL(bind(fd, (struct sockaddr *)&addr, sizeof(addr)), -1);
SAFE_CALL(listen(fd, SERVER_BACKLOG), -1);
return fd;
}
- เจจเฉเจ เจเจฐเฉ เจเจฟ เจธเจพเจเจ เจธเจผเฉเจฐเฉ เจตเจฟเฉฑเจ เจซเจฒเฉเจ เจฆเฉ เจตเจฐเจคเฉเจ เจเจฐเจเฉ เจเฉเจฐ-เจฌเจฒเจพเจเจฟเฉฐเจ เจฎเฉเจก เจตเจฟเฉฑเจ เจฌเจฃเจพเจเจ เจเจฟเจ เจนเฉ
SOCK_NONBLOCK
เจเจธ เจฒเจ เจซเฉฐเจเจธเจผเจจ เจตเจฟเฉฑเจon_accept()
(เจนเฉเจฐ เจชเฉเฉเจนเฉ) เจธเจฟเจธเจเจฎ เจเจพเจฒaccept()
เจฅเจฐเจฟเฉฑเจก เจเจเจเจผเฉเจเจฟเจเจธเจผเจจ เจจเฉเฉฐ เจจเจนเฉเจ เจฐเฉเจเจฟเจเฅค - เจเฉ
reuse_port
เจฌเจฐเจพเจฌเจฐtrue
, เจซเจฟเจฐ เจเจน เจซเฉฐเจเจธเจผเจจ เจธเจพเจเจ เจจเฉเฉฐ เจตเจฟเจเจฒเจช เจฆเฉ เจจเจพเจฒ เจเฉเจเจซเจฟเจเจฐ เจเจฐเฉเจเจพ เจฆเฉเจเจฐเจพSO_REUSEPORT
เจฎเจฒเจเฉ-เจฅเฉเจฐเฉเจกเจก เจตเจพเจคเจพเจตเจฐเจฃ เจตเจฟเฉฑเจ เจเฉฑเจเฉ เจชเฉเจฐเจ เจฆเฉ เจตเจฐเจคเฉเจ เจเจฐเจจ เจฒเจ ("เจฎเจฒเจเฉ-เจฅเฉเจฐเฉเจกเจก เจธเจฐเจตเจฐ" เจญเจพเจ เจตเฉเจเฉ)เฅคsetsockopt()
เจเจตเฉเจเจ เจนเฉเจเจกเจฒเจฐ on_accept()
OS เจฆเฉเจเจฐเจพ เจเฉฑเจ เจเจตเฉเจเจ เจคเจฟเจเจฐ เจเจฐเจจ เจคเฉเจ เจฌเจพเจ
เจฆ เจเจพเจฒ เจเฉเจคเฉ เจเจพเจเจฆเฉ เจนเฉ EPOLLIN
, เจเจธ เจเฉเจธ เจตเจฟเฉฑเจ เจฎเจคเจฒเจฌ เจนเฉ เจเจฟ เจจเจตเจพเจ เจเฉเจจเฉเจเจธเจผเจจ เจธเจตเฉเจเจพเจฐ เจเฉเจคเจพ เจเจพ เจธเจเจฆเจพ เจนเฉเฅค on_accept()
เจเฉฑเจ เจจเจตเจพเจ เจเจจเฉเจเจธเจผเจจ เจธเจตเฉเจเจพเจฐ เจเจฐเจฆเจพ เจนเฉ, เจเจธเจจเฉเฉฐ เจเฉเจฐ-เจฌเจฒเฉเจเจฟเฉฐเจ เจฎเฉเจก เจตเจฟเฉฑเจ เจฌเจฆเจฒเจฆเจพ เจนเฉ เจ
เจคเฉ เจเฉฑเจ เจเจตเฉเจเจ เจนเฉเจเจกเจฒเจฐ เจจเจพเจฒ เจฐเจเจฟเจธเจเจฐ เจเจฐเจฆเจพ เจนเฉ on_recv()
เจเฉฑเจ I/O เจฐเจฟเจเจเจเจฐ เจตเจฟเฉฑเจ.
on_accept() เจซเฉฐเจเจธเจผเจจ เจฆเจฟเจเจพเจ
static void on_accept(void *arg, int fd, uint32_t events) {
int incoming_conn;
SAFE_CALL((incoming_conn = accept(fd, NULL, NULL)), -1);
set_nonblocking(incoming_conn);
SAFE_CALL(reactor_register(reactor, incoming_conn, EPOLLIN, on_recv,
request_buffer_new()),
-1);
}
เจเจตเฉเจเจ เจนเฉเจเจกเจฒเจฐ on_recv()
OS เจฆเฉเจเจฐเจพ เจเฉฑเจ เจเจตเฉเจเจ เจคเจฟเจเจฐ เจเจฐเจจ เจคเฉเจ เจฌเจพเจ
เจฆ เจเจพเจฒ เจเฉเจคเฉ เจเจพเจเจฆเฉ เจนเฉ EPOLLIN
, เจเจธ เจเฉเจธ เจตเจฟเฉฑเจ เจฎเจคเจฒเจฌ เจนเฉ เจเจฟ เจเฉเจจเฉเจเจธเจผเจจ เจฐเจเจฟเจธเจเจฐ เจเฉเจคเจพ เจเจฟเจ เจนเฉ on_accept()
, เจกเจพเจเจพ เจชเฉเจฐเจพเจชเจค เจเจฐเจจ เจฒเจ เจคเจฟเจเจฐ เจนเฉเฅค
on_recv()
เจเจจเฉเจเจธเจผเจจ เจคเฉเจ เจกเจพเจเจพ เจชเฉเฉเจนเจฆเจพ เจนเฉ เจเจฆเฉเจ เจคเฉฑเจ HTTP เจฌเฉเจจเจคเฉ เจชเฉเจฐเฉ เจคเจฐเฉเจนเจพเจ เจชเฉเจฐเจพเจชเจค เจจเจนเฉเจ เจนเฉ เจเจพเจเจฆเฉ, เจซเจฟเจฐ เจเจน เจเฉฑเจ เจนเฉเจเจกเจฒเจฐ เจจเฉเฉฐ เจฐเจเจฟเจธเจเจฐ เจเจฐเจฆเจพ เจนเฉ on_send()
เจเฉฑเจ HTTP เจเจตเจพเจฌ เจญเฉเจเจฃ เจฒเจ. เจเฉเจเจฐ เจเจฒเจพเจเฉฐเจ เจเฉเจจเฉเจเจธเจผเจจ เจคเฉเฉเจฆเจพ เจนเฉ, เจคเจพเจ เจธเจพเจเจ เจจเฉเฉฐ เจฐเจเจฟเจธเจเจฐเจก เจ
เจคเฉ เจฌเฉฐเจฆ เจเจฐ เจฆเจฟเฉฑเจคเจพ เจเจพเจเจฆเจพ เจนเฉ close()
เจซเฉฐเจเจธเจผเจจ on_recv() เจฆเจฟเจเจพเจ
static void on_recv(void *arg, int fd, uint32_t events) {
RequestBuffer *buffer = arg;
// ะัะธะฝะธะผะฐะตะผ ะฒั
ะพะดะฝัะต ะดะฐะฝะฝัะต ะดะพ ัะตั
ะฟะพั, ััะพ recv ะฒะพะทะฒัะฐัะธั 0 ะธะปะธ ะพัะธะฑะบั
ssize_t nread;
while ((nread = recv(fd, buffer->data + buffer->size,
REQUEST_BUFFER_CAPACITY - buffer->size, 0)) > 0)
buffer->size += nread;
// ะะปะธะตะฝั ะพะฑะพัะฒะฐะป ัะพะตะดะธะฝะตะฝะธะต
if (nread == 0) {
SAFE_CALL(reactor_deregister(reactor, fd), -1);
SAFE_CALL(close(fd), -1);
request_buffer_destroy(buffer);
return;
}
// read ะฒะตัะฝัะป ะพัะธะฑะบั, ะพัะปะธัะฝัั ะพั ะพัะธะฑะบะธ, ะฟัะธ ะบะพัะพัะพะน ะฒัะทะพะฒ ะทะฐะฑะปะพะบะธััะตั
// ะฟะพัะพะบ
if (errno != EAGAIN && errno != EWOULDBLOCK) {
request_buffer_destroy(buffer);
fail("read");
}
// ะะพะปััะตะฝ ะฟะพะปะฝัะน HTTP ะทะฐะฟัะพั ะพั ะบะปะธะตะฝัะฐ. ะขะตะฟะตัั ัะตะณะธัััะธััะตะผ ะพะฑัะฐะฑะพััะธะบะฐ
// ัะพะฑััะธะน ะดะปั ะพัะฟัะฐะฒะบะธ ะดะฐะฝะฝัั
if (request_buffer_is_complete(buffer)) {
request_buffer_clear(buffer);
SAFE_CALL(reactor_reregister(reactor, fd, EPOLLOUT, on_send, buffer),
-1);
}
}
เจเจตเฉเจเจ เจนเฉเจเจกเจฒเจฐ on_send()
OS เจฆเฉเจเจฐเจพ เจเฉฑเจ เจเจตเฉเจเจ เจคเจฟเจเจฐ เจเจฐเจจ เจคเฉเจ เจฌเจพเจ
เจฆ เจเจพเจฒ เจเฉเจคเฉ เจเจพเจเจฆเฉ เจนเฉ EPOLLOUT
, เจฎเจคเจฒเจฌ เจเจฟ เจเฉเจจเฉเจเจธเจผเจจ เจฐเจเจฟเจธเจเจฐ เจนเฉเจเจ เจนเฉ on_recv()
, เจกเจพเจเจพ เจญเฉเจเจฃ เจฒเจ เจคเจฟเจเจฐ เจนเฉเฅค เจเจน เจซเฉฐเจเจธเจผเจจ เจเจฒเจพเจเฉฐเจ เจจเฉเฉฐ เจเฉฑเจ เจเจฟเฉฑเจคเจฐ เจฆเฉ เจจเจพเจฒ HTML เจตเจพเจฒเจพ เจเฉฑเจ HTTP เจเจตเจพเจฌ เจญเฉเจเจฆเจพ เจนเฉ เจ
เจคเฉ เจซเจฟเจฐ เจเจตเฉเจเจ เจนเฉเจเจกเจฒเจฐ เจจเฉเฉฐ เจตเจพเจชเจธ เจตเจฟเฉฑเจ เจฌเจฆเจฒเจฆเจพ เจนเฉ on_recv()
.
on_send() เจซเฉฐเจเจธเจผเจจ เจฆเจฟเจเจพเจ
static void on_send(void *arg, int fd, uint32_t events) {
const char *content = "<img "
"src="https://habrastorage.org/webt/oh/wl/23/"
"ohwl23va3b-dioerobq_mbx4xaw.jpeg">";
char response[1024];
sprintf(response,
"HTTP/1.1 200 OK" CRLF "Content-Length: %zd" CRLF "Content-Type: "
"text/html" DOUBLE_CRLF "%s",
strlen(content), content);
SAFE_CALL(send(fd, response, strlen(response), 0), -1);
SAFE_CALL(reactor_reregister(reactor, fd, EPOLLIN, on_recv, arg), -1);
}
เจ
เจคเฉ เจ
เฉฐเจค เจตเจฟเฉฑเจ, เจซเจพเจเจฒ เจตเจฟเฉฑเจ http_server.c
, เจซเฉฐเจเจธเจผเจจ เจตเจฟเฉฑเจ main()
เจ
เจธเฉเจ เจตเจฐเจค เจเฉ เจเฉฑเจ I/O เจฐเจฟเจเจเจเจฐ เจฌเจฃเจพเจเจเจฆเฉ เจนเจพเจ reactor_new()
, เจเฉฑเจ เจธเจฐเจตเจฐ เจธเจพเจเจ เจฌเจฃเจพเจ เจ
เจคเฉ เจเจธเจจเฉเฉฐ เจฐเจเจฟเจธเจเจฐ เจเจฐเฉ, เจฐเจฟเจเจเจเจฐ เจฆเฉ เจตเจฐเจคเฉเจ เจเจฐเจเฉ เจธเจผเฉเจฐเฉ เจเจฐเฉ reactor_run()
เจฌเจฟเจฒเจเฉเจฒ เจเฉฑเจ เจฎเจฟเฉฐเจ เจฒเจ, เจ
เจคเฉ เจซเจฟเจฐ เจ
เจธเฉเจ เจธเจฐเฉเจค เจเจพเจฐเฉ เจเจฐเจฆเฉ เจนเจพเจ เจ
เจคเฉ เจชเฉเจฐเฉเจเจฐเจพเจฎ เจคเฉเจ เจฌเจพเจนเจฐ เจ เจเจพเจเจฆเฉ เจนเจพเจเฅค
http_server.c เจฆเจฟเจเจพเจ
#include "reactor.h"
static Reactor *reactor;
#include "common.h"
int main(void) {
SAFE_CALL((reactor = reactor_new()), NULL);
SAFE_CALL(
reactor_register(reactor, new_server(false), EPOLLIN, on_accept, NULL),
-1);
SAFE_CALL(reactor_run(reactor, SERVER_TIMEOUT_MILLIS), -1);
SAFE_CALL(reactor_destroy(reactor), -1);
}
เจเจ เจเจพเจเจ เจเจฐเฉเจ เจเจฟ เจธเจญ เจเฉเจ เจเจฎเฉเจฆ เจ
เจจเฉเจธเจพเจฐ เจเฉฐเจฎ เจเจฐ เจฐเจฟเจนเจพ เจนเฉเฅค เจเฉฐเจชเจพเจเจฒเจฟเฉฐเจ (chmod a+x compile.sh && ./compile.sh
เจชเฉเจฐเฉเจเฉเจเจ เจฐเฉเจ เจตเจฟเฉฑเจ) เจ
เจคเฉ เจธเจตเฉ-เจฒเจฟเจเจค เจธเจฐเจตเจฐ เจจเฉเฉฐ เจฒเจพเจเจ เจเจฐเฉ, เจเฉเจฒเฉเจนเฉ
เจชเฉเจฐเจฆเจฐเจธเจผเจจ เจฎเจพเจช
เจฎเฉเจฐเฉ เจเจพเจฐ เจฆเฉเจเจ เจตเจฟเจธเจผเฉเจธเจผเจคเจพเจตเจพเจ เจฆเจฟเจเจพเจ
$ screenfetch
MMMMMMMMMMMMMMMMMMMMMMMMMmds+. OS: Mint 19.1 tessa
MMm----::-://////////////oymNMd+` Kernel: x86_64 Linux 4.15.0-20-generic
MMd /++ -sNMd: Uptime: 2h 34m
MMNso/` dMM `.::-. .-::.` .hMN: Packages: 2217
ddddMMh dMM :hNMNMNhNMNMNh: `NMm Shell: bash 4.4.20
NMm dMM .NMN/-+MMM+-/NMN` dMM Resolution: 1920x1080
NMm dMM -MMm `MMM dMM. dMM DE: Cinnamon 4.0.10
NMm dMM -MMm `MMM dMM. dMM WM: Muffin
NMm dMM .mmd `mmm yMM. dMM WM Theme: Mint-Y-Dark (Mint-Y)
NMm dMM` ..` ... ydm. dMM GTK Theme: Mint-Y [GTK2/3]
hMM- +MMd/-------...-:sdds dMM Icon Theme: Mint-Y
-NMm- :hNMNNNmdddddddddy/` dMM Font: Noto Sans 9
-dMNs-``-::::-------.`` dMM CPU: Intel Core i7-6700 @ 8x 4GHz [52.0ยฐC]
`/dMNmy+/:-------------:/yMMM GPU: NV136
./ydNMMMMMMMMMMMMMMMMMMMMM RAM: 2544MiB / 7926MiB
.MMMMMMMMMMMMMMMMMMM
เจเจ เจเฉฑเจ เจธเจฟเฉฐเจเจฒ-เจฅเฉเจฐเฉเจกเจก เจธเจฐเจตเจฐ เจฆเฉ เจเจพเจฐเจเฉเจเจผเจพเจฐเฉ เจจเฉเฉฐ เจฎเจพเจชเฉเจเฅค เจเจ เจฆเฉ เจเจฐเจฎเฉเจจเจฒ เจเฉเจฒเฉเจนเฉเจ: เจเฉฑเจ เจตเจฟเฉฑเจ เจ
เจธเฉเจ เจเฉฑเจฒเจพเจเจเฉ ./http_server
, เจเฉฑเจ เจตเฉฑเจเจฐเฉ เจตเจฟเฉฑเจ -
$ wrk -c100 -d1m -t8 http://127.0.0.1:18470 -H "Host: 127.0.0.1:18470" -H "Accept-Language: en-US,en;q=0.5" -H "Connection: keep-alive"
Running 1m test @ http://127.0.0.1:18470
8 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 493.52us 76.70us 17.31ms 89.57%
Req/Sec 24.37k 1.81k 29.34k 68.13%
11657769 requests in 1.00m, 1.60GB read
Requests/sec: 193974.70
Transfer/sec: 27.19MB
เจธเจพเจกเจพ เจธเจฟเฉฐเจเจฒ-เจฅเฉเจฐเฉเจกเจก เจธเจฐเจตเจฐ 11 เจเฉเจจเฉเจเจธเจผเจจเจพเจ เจคเฉเจ เจชเฉเจฆเจพ เจนเฉเจฃ เจตเจพเจฒเฉเจเจ เจชเฉเจฐเจคเฉ เจฎเจฟเฉฐเจ 100 เจฎเจฟเจฒเฉเจ เจจ เจฌเฉเจจเจคเฉเจเจ เจฆเฉ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจเจฐเจจ เจฆเฉ เจฏเฉเจ เจธเฉเฅค เจฌเฉเจฐเจพ เจจเจคเฉเจเจพ เจจเจนเฉเจ, เจชเจฐ เจเฉ เจเจธ เจจเฉเฉฐ เจธเฉเจงเจพเจฐเจฟเจ เจเจพ เจธเจเจฆเจพ เจนเฉ?
เจฎเจฒเจเฉเจฅเฉเจฐเฉเจกเจก เจธเจฐเจตเจฐ
เจเจฟเจตเฉเจ เจเฉฑเจชเจฐ เจฆเฉฑเจธเจฟเจ เจเจฟเจ เจนเฉ, I/O เจฐเจฟเจเจเจเจฐ เจจเฉเฉฐ เจตเฉฑเจเจฐเฉ เจฅเฉเจฐเฉเจกเจพเจ เจตเจฟเฉฑเจ เจฌเจฃเจพเจเจ เจเจพ เจธเจเจฆเจพ เจนเฉ, เจเจธ เจคเจฐเฉเจนเจพเจ เจธเจพเจฐเฉ CPU เจเฉเจฐเจพเจ เจฆเฉ เจตเจฐเจคเฉเจ เจเฉเจคเฉ เจเจพ เจธเจเจฆเฉ เจนเฉเฅค เจเจ เจเจธ เจชเจนเฉเฉฐเจ เจจเฉเฉฐ เจ เจฎเจฒ เจตเจฟเฉฑเจ เจฒเจฟเจเจเจ:
http_server_multithreaded.c เจฆเจฟเจเจพเจ
#include "reactor.h"
static Reactor *reactor;
#pragma omp threadprivate(reactor)
#include "common.h"
int main(void) {
#pragma omp parallel
{
SAFE_CALL((reactor = reactor_new()), NULL);
SAFE_CALL(reactor_register(reactor, new_server(true), EPOLLIN,
on_accept, NULL),
-1);
SAFE_CALL(reactor_run(reactor, SERVER_TIMEOUT_MILLIS), -1);
SAFE_CALL(reactor_destroy(reactor), -1);
}
}
เจนเฉเจฃ เจนเจฐ เจฅเจฐเจฟเฉฑเจก
static Reactor *reactor;
#pragma omp threadprivate(reactor)
เจเจฟเจฐเจชเจพ เจเจฐเจเฉ เจงเจฟเจเจจ เจฆเจฟเจ เจเจฟ เจซเฉฐเจเจธเจผเจจ เจเจฐเจเฉเจฎเฉเจเจ new_server()
เจฎเจฟเจนเจฐเจฌเจพเจจเฉ เจเจฐเจฆเจพ เจนเฉ true
. เจเจธเจฆเจพ เจฎเจคเจฒเจฌ เจนเฉ เจเจฟ เจ
เจธเฉเจ เจธเจฐเจตเจฐ เจธเจพเจเจ เจจเฉเฉฐ เจตเจฟเจเจฒเจช เจธเฉเจเจชเจฆเฉ เจนเจพเจ SO_REUSEPORT
เจฆเฉเจเฉ เจฆเฉเฉ
เจเจ เจนเฉเจฃ เจฎเจฒเจเฉ-เจฅเฉเจฐเฉเจกเจก เจธเจฐเจตเจฐ เจฆเฉ เจเจพเจฐเจเฉเจเจผเจพเจฐเฉ เจจเฉเฉฐ เจฎเจพเจชเฉเจ:
$ wrk -c100 -d1m -t8 http://127.0.0.1:18470 -H "Host: 127.0.0.1:18470" -H "Accept-Language: en-US,en;q=0.5" -H "Connection: keep-alive"
Running 1m test @ http://127.0.0.1:18470
8 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 1.14ms 2.53ms 40.73ms 89.98%
Req/Sec 79.98k 18.07k 154.64k 78.65%
38208400 requests in 1.00m, 5.23GB read
Requests/sec: 635876.41
Transfer/sec: 89.14MB
1 เจฎเจฟเฉฐเจ เจตเจฟเฉฑเจ เจชเฉเจฐเฉเจธเฉเจธ เจเฉเจคเฉเจเจ เจเจเจเจ เจฌเฉเจจเจคเฉเจเจ เจฆเฉ เจเจฟเจฃเจคเฉ ~3.28 เจเฉเจฃเจพ เจตเจง เจเจ เจนเฉ! เจชเจฐ เจ เจธเฉเจ เจฐเจพเจเจเจก เจจเฉฐเจฌเจฐ เจคเฉเจ เจธเจฟเจฐเจซ ~XNUMX เจฎเจฟเจฒเฉเจ เจจ เจเฉฑเจ เจธเฉ, เจเจธ เจฒเจ เจเจ เจเจธเจจเฉเฉฐ เจ เฉเจ เจเจฐเจจ เจฆเฉ เจเฉเจธเจผเจฟเจธเจผ เจเจฐเฉเจเฅค
เจชเจนเจฟเจฒเจพเจ เจเจจเจฐเฉเจ เจเฉเจคเฉ เจเจ เจ
เฉฐเจเฉเจฟเจเจ เจจเฉเฉฐ เจฆเฉเจเฉเจ
$ sudo perf stat -B -e task-clock,context-switches,cpu-migrations,page-faults,cycles,instructions,branches,branch-misses,cache-misses ./http_server_multithreaded
Performance counter stats for './http_server_multithreaded':
242446,314933 task-clock (msec) # 4,000 CPUs utilized
1โฏ813โฏ074 context-switches # 0,007 M/sec
4โฏ689 cpu-migrations # 0,019 K/sec
254 page-faults # 0,001 K/sec
895โฏ324โฏ830โฏ170 cycles # 3,693 GHz
621โฏ378โฏ066โฏ808 instructions # 0,69 insn per cycle
119โฏ926โฏ709โฏ370 branches # 494,653 M/sec
3โฏ227โฏ095โฏ669 branch-misses # 2,69% of all branches
808โฏ664 cache-misses
60,604330670 seconds time elapsed
-march=native
, MAX_EVENTS
เจ
เจคเฉ เจตเจฐเจคเฉ EPOLLET
เจชเฉเจฐเจฆเจฐเจธเจผเจจ เจตเจฟเฉฑเจ เจเฉฑเจ เจฎเจนเฉฑเจคเจตเจชเฉเจฐเจจ เจตเจพเจงเจพ เจจเจนเฉเจ เจฆเจฟเฉฑเจคเจพ. เจชเจฐ เจเฉ เจคเฉเจธเฉเจ เจธเจฎเจเจพเจฒเฉ เจเฉเจจเฉเจเจธเจผเจจเจพเจ เจฆเฉ เจเจฟเจฃเจคเฉ เจตเจงเจพเจเจเจฆเฉ เจนเฉ เจคเจพเจ เจเฉ เจนเฉเฉฐเจฆเจพ เจนเฉ?
352 เจเฉฑเจเฉ เจธเจฎเฉเจ เจฆเฉ เจเจจเฉเจเจธเจผเจจเจพเจ เจฒเจ เจ เฉฐเจเฉเฉ:
$ wrk -c352 -d1m -t8 http://127.0.0.1:18470 -H "Host: 127.0.0.1:18470" -H "Accept-Language: en-US,en;q=0.5" -H "Connection: keep-alive"
Running 1m test @ http://127.0.0.1:18470
8 threads and 352 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 2.12ms 3.79ms 68.23ms 87.49%
Req/Sec 83.78k 12.69k 169.81k 83.59%
40006142 requests in 1.00m, 5.48GB read
Requests/sec: 665789.26
Transfer/sec: 93.34MB
เจฒเฉเฉเฉเจเจฆเจพ เจจเจคเฉเจเจพ เจชเฉเจฐเจพเจชเจค เจเฉเจคเจพ เจเจฟเจ เจธเฉ, เจ เจคเฉ เจเจธเจฆเฉ เจจเจพเจฒ เจเฉฑเจ เจฆเจฟเจฒเจเจธเจช เจเฉเจฐเจพเจซเจผ เจเจจเฉเจเจธเจผเจจเจพเจ เจฆเฉ เจธเฉฐเจเจฟเจ 'เจคเฉ 1 เจฎเจฟเฉฐเจ เจตเจฟเฉฑเจ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจเฉเจคเฉเจเจ เจฌเฉเจจเจคเฉเจเจ เจฆเฉ เจเจฟเจฃเจคเฉ เจฆเฉ เจจเจฟเจฐเจญเจฐเจคเจพ เจจเฉเฉฐ เจฆเจฐเจธเจพเจเจเจฆเจพ เจนเฉ:
เจ เจธเฉเจ เจฆเฉเจเจฆเฉ เจนเจพเจ เจเจฟ เจฆเฉ เจธเฉ เจเฉเจจเฉเจเจธเจผเจจเจพเจ เจคเฉเจ เจฌเจพเจ เจฆ, เจฆเฉเจตเจพเจ เจธเจฐเจตเจฐเจพเจ เจฒเจ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจเฉเจคเฉเจเจ เจฌเฉเจจเจคเฉเจเจ เจฆเฉ เจเจฟเจฃเจคเฉ เจคเฉเจเจผเฉ เจจเจพเจฒ เจเฉฑเจ เจเจพเจเจฆเฉ เจนเฉ (เจฎเจฒเจเฉ-เจฅเฉเจฐเฉเจกเจก เจธเฉฐเจธเจเจฐเจฃ เจตเจฟเฉฑเจ เจเจน เจตเจงเฉเจฐเฉ เจงเจฟเจเจจ เจฆเฉเจฃ เจฏเฉเจ เจนเฉ)เฅค เจเฉ เจเจน เจฒเฉเจจเจเจธ TCP/IP เจธเจเฉเจ เจฒเจพเจเฉ เจเจฐเจจ เจจเจพเจฒ เจธเจฌเฉฐเจงเจค เจนเฉ? เจเจฟเฉฑเจชเจฃเฉเจเจ เจตเจฟเฉฑเจ เจฎเจฒเจเฉ-เจฅเฉเจฐเฉเจกเจก เจ เจคเฉ เจธเจฟเฉฐเจเจฒ-เจฅเฉเจฐเฉเจกเจก เจตเจฟเจเจฒเจชเจพเจ เจฒเจ เจเฉเจฐเจพเจซ เจฆเฉ เจเจธ เจตเจฟเจตเจนเจพเจฐ เจ เจคเฉ เจ เจจเฉเจเฉเจฒเจคเจพ เจฌเจพเจฐเฉ เจเจชเจฃเฉเจเจ เจงเจพเจฐเจจเจพเจตเจพเจ เจฒเจฟเจเจฃ เจฒเจ เจธเฉเจคเฉฐเจคเจฐ เจฎเจนเจฟเจธเฉเจธ เจเจฐเฉเฅค
เจเจฐเจจเจพ
I/O เจฐเจฟเจเจเจเจฐ เจฆเฉ เจจเฉเจเจธเจพเจจ
เจคเฉเจนเจพเจจเฉเฉฐ เจเจน เจธเจฎเจเจฃ เจฆเฉ เจฒเฉเฉ เจนเฉ เจเจฟ I/O เจฐเจฟเจเจเจเจฐ เจเจชเจฃเฉเจเจ เจเจฎเฉเจเจ เจคเฉเจ เจฌเจฟเจจเจพเจ เจจเจนเฉเจ เจนเฉ, เจ เจฐเจฅเจพเจค:
- เจฎเจฒเจเฉ-เจฅเจฐเจฟเฉฑเจกเจก เจตเจพเจคเจพเจตเจฐเจฃ เจตเจฟเฉฑเจ เจเฉฑเจ I/O เจฐเจฟเจเจเจเจฐ เจฆเฉ เจตเจฐเจคเฉเจ เจเจฐเจจเจพ เจเฉเจ เจนเฉเจฐ เจฎเฉเจธเจผเจเจฒ เจนเฉ, เจเจฟเจเจเจเจฟ เจคเฉเจนเจพเจจเฉเฉฐ เจนเฉฑเจฅเฉเจ เจชเฉเจฐเจตเจพเจน เจฆเจพ เจชเฉเจฐเจฌเฉฐเจงเจจ เจเจฐเจจเจพ เจชเจเจเจพเฅค
- เจ เจญเจฟเจเจธ เจฆเจฟเจเจพเจเจเจฆเจพ เจนเฉ เจเจฟ เจเจผเจฟเจเจฆเจพเจคเจฐ เจฎเจพเจฎเจฒเจฟเจเจ เจตเจฟเฉฑเจ เจฒเฉเจก เจเฉเจฐ-เจฏเฉเจจเฉเจซเจพเจฐเจฎ เจนเฉเฉฐเจฆเจพ เจนเฉ, เจเจฟเจธ เจจเจพเจฒ เจเฉฑเจ เจฅเจฐเจฟเฉฑเจก เจฒเฉเจเจฟเฉฐเจ เจนเฉ เจธเจเจฆเจพ เจนเฉ เจเจฆเฉเจ เจเจฟ เจฆเฉเจเจพ เจเฉฐเจฎ เจตเจฟเฉฑเจ เจฐเฉเฉฑเจเจฟเจ เจนเฉเฉฐเจฆเจพ เจนเฉเฅค
- เจเฉเจเจฐ เจเฉฑเจ เจเจตเฉเจเจ เจนเฉเจเจกเจฒเจฐ เจเฉฑเจ เจฅเจฐเจฟเฉฑเจก เจจเฉเฉฐ เจฌเจฒเฉเจ เจเจฐเจฆเจพ เจนเฉ, เจคเจพเจ เจธเจฟเจธเจเจฎ เจเฉเจฃเจเจพเจฐ เจเฉเจฆ เจตเฉ เจฌเจฒเฉเจ เจเจฐ เจฆเฉเจตเฉเจเจพ, เจเจฟเจธ เจจเจพเจฒ เจฒเฉฑเจญเจฃ เจตเจฟเฉฑเจ เจฎเฉเจธเจผเจเจฒ เจฌเฉฑเจ เจนเฉ เจธเจเจฆเฉ เจนเจจเฅค
เจเจนเจจเจพเจ เจธเจฎเฉฑเจธเจฟเจเจตเจพเจ เจจเฉเฉฐ เจนเฉฑเจฒ เจเจฐเจฆเจพ เจนเฉ
เจธเจฟเฉฑเจเจพ
เจเจน เจเจน เจฅเจพเจ เจนเฉ เจเจฟเฉฑเจฅเฉ เจธเจฟเจงเจพเจเจค เจคเฉเจ เจธเจฟเฉฑเจงเจพ เจชเฉเจฐเฉเจซเจพเจเจฒเจฐ เจเจเจเจผเฉเจธเจ เจคเฉฑเจ เจธเจพเจกเฉ เจฏเจพเจคเจฐเจพ เจเจคเจฎ เจนเฉ เจเจ เจนเฉเฅค
เจคเฉเจนเจพเจจเฉเฉฐ เจเจธ 'เจคเฉ เจงเจฟเจเจจ เจจเจนเฉเจ เจฆเฉเจฃเจพ เจเจพเจนเฉเจฆเจพ, เจเจฟเจเจเจเจฟ เจตเฉฑเจ-เจตเฉฑเจ เจชเฉฑเจงเจฐเจพเจ เจฆเฉ เจธเจนเฉเจฒเจค เจ เจคเฉ เจเจคเฉ เจฆเฉ เจจเจพเจฒ เจจเฉเฉฑเจเจตเจฐเจ เจธเฉเจซเจเจตเฉเจ เจฐ เจฒเจฟเจเจฃ เจฒเจ เจฌเจนเฉเจค เจธเจพเจฐเฉ เจนเฉเจฐ เจฌเจฐเจพเจฌเจฐ เจฆเจฟเจฒเจเจธเจช เจคเจฐเฉเจเฉ เจนเจจเฅค เจฆเจฟเจฒเจเจธเจช, เจฎเฉเจฐเฉ เจฐเจพเจ เจตเจฟเฉฑเจ, เจฒเจฟเฉฐเจ เจนเฉเจ เจพเจ เจฆเจฟเฉฑเจคเฉ เจเจ เจนเจจ.
DO ะฝะพะฒัั ะฒัััะตั!
เจฆเจฟเจฒเจเจธเจช เจชเฉเจฐเฉเจเฉเจเจ
- เจธเฉ
เจเฉฐเจเจพเจฒ
เจฎเฉเจจเฉเฉฐ เจนเฉเจฐ เจเฉ เจชเฉเฉเจนเจจเจพ เจเจพเจนเฉเจฆเจพ เจนเฉ?
https://linux.die.net/man/7/socket https://stackoverflow.com/questions/1050222/what-is-the-difference-between-concurrency-and-parallelism http://www.kegel.com/c10k.html https://kernel.dk/io_uring.pdf https://aturon.github.io/blog/2016/09/07/futures-design/ https://tokio.rs/blog/2019-10-scheduler/ https://www.artima.com/articles/io_design_patterns.html https://habr.com/en/post/183832/
เจธเจฐเฉเจค: www.habr.com