ืืงืืื
ืืื ืืขื ืึทืจืืืงื, ืืืจ ืืืขืื ืงืืงื ืืื ืื ืื ืก ืืื ืึทืืฅ ืคืื ืึทื I/O ืจืขืึทืงืืึธืจ ืืื ืืื ืขืก ืึทืจืืขื, ืฉืจืืึทืื ืึทื ืืืคึผืืึทืืขื ืืืืฉืึทื ืืื ืืืืื ืืงืขืจ ืืื 200 ืฉืืจืืช ืคืื ืงืึธื ืืื ืืึทืื ืึท ืคึผืฉืื ืืืืคึผ ืกืขืจืืืขืจ ืคึผืจืึธืฆืขืก ืืืืขืจ 40 ืืืืืึธื ืจืืงืืืขืก / ืืื.
ืืึทืืืึธืืข
- ืืขืจ ืึทืจืืืงื ืืื ืืขืืืขื ืืขืฉืจืืื ืฆื ืืขืืคื ืคึฟืึทืจืฉืืืื ืื ืคืึทื ืืงืฉืึทื ืื ื ืคืื ืื ื / ืึธ ืจืขืึทืงืืึธืจ, ืืื ืืขืจืืืขืจ ืคึฟืึทืจืฉืืืื ืื ืจืืกืงืก ืืืขื ืืืจ ื ืืฆื ืขืก.
- ืืืืกื ืคืื ืื ืืึทืกืืงืก ืืื ืคืืจืืื ืื ืฆื ืคึฟืึทืจืฉืืืื ืืขื ืึทืจืืืงื.
C ืฉืคึผืจืึทื ืืื ืขืืืขืืข ืืขืจืคืึทืจืื ื ืืื ื ืขืฅ ืึทืคึผืืึทืงืืืฉืึทื ืึทื ืืืืืงืืื ื. - ืึทืืข ืงืึธื ืืื ืืขืฉืจืืื ืืื C ืฉืคึผืจืึทื ืฉืืจืขื ื ืืืื ืฆื (ืืืึธืจืขื ืขื: ืืึทื ื ืคึผืืฃ)
ืฆื C11 ื ืึธืจืืึทื ืคึฟืึทืจ ืืื ืืงืก ืืื ืื ืืืฆื ืืืืฃืืืืืื .
ืคืืจืืืืก ืืื ืืึธืก ื ืืืืืง?
ืืื ืื ืืจืึธืืื ื ืคึผืึธืคึผืืืึทืจืืืขื ืคืื ืืขืจ ืืื ืืขืจื ืขืฅ, ืืืขื ืกืขืจืืืขืจืก ืื ืืขืืืืื ืฆื ืฉืขืคึผื ืึท ืืจืืืก ื ืืืขืจ ืคืื ืงืึทื ืขืงืฉืึทื ื ืกืืืืึทืืืืื ืืึทืกืื, ืืื ืืขืจืืืขืจ ืฆืืืื ืึทืคึผืจืึธืืืฉืื ืืขื ืขื ืืขืคืจืืืื: ืืืึทืงืื ื I/O ืืืืฃ ืึท ืืจืืืก ื ืืืขืจ ืคืื ืึทืก ืคึฟืขืืขื ืืื ื ืื-ืืืึทืงืื ื I/O ืืื ืงืึธืืืื ืึทืฆืืข ืืื ืึท ืืขืฉืขืขื ืืฉ ืึธื ืืึธื ืกืืกืืขื, ืืืื ืืขืจืืคื "ืกืืกืืขื ืกืขืืขืงืืึธืจ" (
ืืขืจ ืขืจืฉืืขืจ ืฆืืืึทื ื ืื ืืืึทืืืื ืงืจืืืืืื ื ืึท ื ืืึท ืึทืก ืคืึธืืขื ืคึฟืึทืจ ืืขืืขืจ ืื ืงืึทืืื ื ืงืฉืจ. ืืืึทื ืืืกืึธืจื ืืื ื ืขืืขื ืกืงืึทืืึทืืืืืื: ืื ืึธืคึผืขืจืืืืื ื ืกืืกืืขื ืืืขื ืืึธืื ืฆื ืื ืกืืจืืืขื ื ืคืืืข
ืื ืืึทืืึทืคืืื ืืืขืจืกืืข ืืืืืืืฅ
ืื ืจืืข ืฆืืืึทื ื ื ืืฆื
ืืขืจ ืืืืืง ืฆืืืืฉื ืื ืึทืคึผืจืึธืืืฉืื ืืื ืืื ืืืื:
- ืืืึทืงืื ื ืืื / ืึธ ืึทืคึผืขืจืืืฉืึทื ื ืกืืกืคึผืขื ืืืจื ืืึทื ืืฆืขืจ ืืืืคื ืืืืืื ืื ืึทืก ืืื ืจืขืื
ืืขืคืจืึทืืืึทื ืฅ ืื ืงืึทืืื ืIP ืคึผืึทืงืืฅ ืฆื ืืืื ืกืืจืื (ืืงืคึผ , ืจืืกืืืืื ื ืืึทืื) ืึธืืขืจ ืขืก ืืืขื ื ืืฉื ืืืื ืืขื ืื ืคึผืืึทืฅ ืื ืืืฆื ืืื ืื ืื ืขืจืืขื ืฉืจืืึทืื ืืึทืคืขืจื ืคึฟืึทืจ ืกืึทืืกืึทืงืืืึทื ื ืฉืืงื ืืืจืื ืืง (ืฉืืงื ืืึทืื). - ืกืืกืืขื ืกืขืืขืงืืึธืจ ืืื ืื ืฆืืื ื ืึธืืืึทืคืืื ืื ืคึผืจืึธืืจืึทื ืึทื ืื ืึทืก ืฉืืื ืืขืคืจืึทืืืขื ืืขื IP ืคึผืึทืงืืฅ (ืืงืคึผ, ืืึทืื ืึธืคึผืืจืึธื) ืึธืืขืจ ืืขื ืื ืคึผืืึทืฅ ืืื ืื ืขืจืืขื ืฉืจืืึทืื ืืึทืคืขืจื ืฉืืื ืื ืืืฆื (ืฉืืงื ืืึทืื).
ืฆื ืกืึทืืึทืงื ืขืก ืึทืจืืืฃ, ืจืืืขืจืืืื ื ืึทื ืึทืก ืคืึธืืขื ืคึฟืึทืจ ืืขืืขืจ ื / ืึธ ืืื ืึท ืืืืกื ืคืื ืงืึทืืคึผืืืืื ื ืืึทืื, ืืืืึทื ืืื ืคืึทืงื, ืื ืคึฟืขืืขื ืืึธื ื ืื ื ืืฆื ื ืืฆืืง ืึทืจืืขื (ืืขืจืืืขืจ ืื ืืขืจืืื
ืืื / ืึธ ืจืขืึทืงืืึธืจ ืืึธืืขื
ืืขืจ I/O ืจืขืึทืงืืึธืจ ืึทืงื ืืื ืึท ืฉืืืืข ืฆืืืืฉื ืื ืกืืกืืขื ืกืขืืขืงืืึธืจ ืืื ืื ืืึทื ืืฆืขืจ ืงืึธื. ืืขืจ ืคึผืจืื ืฆืืคึผ ืคืื ืืืึทื ืึธืคึผืขืจืึทืฆืืข ืืื ืืืกืงืจืืืื ืืืจื ืื ืคืืืืขื ืืข ืืืึธืง ืืืึทืืจืึทืืข:
- ืืึธืื ืืืจ ืืขืจืืึธื ืขื ืืืจ ืึทื ืึท ืืขืฉืขืขื ืืฉ ืืื ืึท ืึธื ืืึธื ืึทื ืึท ืืืืขืจ ืืึธืืขื ืืื ืืืืืืช ืฆื ืืืจืืคืืจื ืึท ื ืื-ืืืึทืงืื ื ื / ืึธ ืึธืคึผืขืจืึทืฆืืข.
- ืึท ืืขืฉืขืขื ืืฉ ืืึทื ืืืขืจ ืืื ืึท ืคึฟืื ืงืฆืืข ืืขืจืืคึฟื ืืืจื ืื ื / ืึธ ืจืขืึทืงืืึธืจ ืืืขื ืึท ืืขืฉืขืขื ืืฉ ืืื ืืืงืืืขื, ืืืึธืก ืืขืืึธืื ืคึผืขืจืคืึธืจืื ืึท ื ืื-ืืืึทืงืื ื ื / ืึธ ืึธืคึผืขืจืึทืฆืืข.
ืขืก ืืื ืืืืืืืง ืฆื ืืึธื ืึทื ืืขืจ I / O ืจืขืึทืงืืึธืจ ืืื ืืืจื ืืขืคึฟืื ืืฆืืข ืืืื-ืืจืขืืื, ืึธืืขืจ ืขืก ืืื ืืึธืจื ืืฉื ืกืืึธืคึผืคึผืื ื ืืขื ืืึทืืจืืฃ ืฆื ืืืื ืืขืืืืื ื ืืื ืึท ืืึทืืื-ืืจืขืืื ืกืืืืืืข ืืื ืึท ืคืึทืจืืขืืืขื ืืฉ ืคืื 1 ืคืึธืืขื: 1 ืจืขืึทืงืืึธืจ, ืืขืจืืื ืจืืกืืืงืืื ื ืึทืืข ืงืคึผื ืงืึธืจืขืก.
ืืืคึผืืขืืขื ืืึทืืืึธื
ืืืจ ืืืขืื ืฉืืขืื ืื ืฆืืืืจ ืฆืืืื ื ืืื ืึท ืืขืงืข reactor.h
reactor.c
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;
}
ืฆื ืกืึทืืขืจืืื, ืื ืงืืื ืคืื ืคืึทื ืืงืฉืึทื ื ืงืึทืืืก ืืื ืืึทื ืืฆืขืจ ืงืึธื ืืืขื ื ืขืืขื ืื ืคืืืืขื ืืข ืคืึธืจืขื:
ืืืื ืืจืขืืื ืกืขืจืืืขืจ
ืืื ืกืืจ ืฆื ืคึผืจืืืืจื ืื ื / ืึธ ืจืขืึทืงืืึธืจ ืืื ืืขืจ ืืืื ืืึทืกืข, ืืืจ ืืืขืื ืฉืจืืึทืื ืึท ืคึผืฉืื ืืืืคึผ ืืืขื ืกืขืจืืืขืจ ืืืึธืก ืจืืกืคึผืึทื ืื ืฆื ืงืืื ืืงืฉื ืืื ืึท ืืืื.
ื ืฉื ืขื ืจืขืคึฟืขืจืขื ืฅ ืฆื ืื ืืืืคึผ ืคึผืจืึธืืึธืงืึธื
ืืืืคึผ ืงืขื ืขื ืืืื ืืืืื ืืขืืืืื ื ืืืืขืจ
ืืขืื ืคึฟืึธืจืืึทื
<ะะะะะะะ> <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/X.Y
. ืื ืืขืจืกื ืงืึทืืึทื ืื ืืขื ืืฆื ืืืขืจืกืืข ืืืึทื ื ืืืHTTP/1.1
.<ะะะะะะะะะ N>
ืืื ืึท ืฉืืืกื-ืืืขืจื ืคึผืึธืจ ืืื ืืขื ืคึฟืึธืจืืึทื<ะะะฎะง>: <ะะะะงะะะะ>
, ืืขืฉืืงื ืฆื ืื ืกืขืจืืืขืจ ืคึฟืึทืจ ืืืืึทืืขืจ ืึทื ืึทืืืกืืก.<ะะะะะซะ>
- ืืึทืื ืคืืจืืื ืื ืืืจื ืื ืกืขืจืืืขืจ ืฆื ืืืจืืคืืจื ืื ืึธืคึผืขืจืึทืฆืืข. ืึธืคื ืขืก ืืื ืคึผืฉืืืืืฉืกืึธื ืึธืืขืจ ืงืืื ืื ืืขืจืข ืคึฟืึธืจืืึทื.
ืขื ืืคืขืจ ืคึฟืึธืจืืึทื
<ะะะ ะกะะฏ 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
ืืืืึทืื ืคึฟืื ืงืฆืืข ืคึผืจืึธืืืึทืืืืคึผืก ืืื ืคึผืจืึธืกื.ื
/*
* ะะฑัะฐะฑะพััะธะบ ัะพะฑััะธะน, ะบะพัะพััะน ะฒัะทะพะฒะตััั ะฟะพัะปะต ัะพะณะพ, ะบะฐะบ ัะพะบะตั ะฑัะดะตั
* ะณะพัะพะฒ ะฟัะธะฝััั ะฝะพะฒะพะต ัะพะตะดะธะฝะตะฝะธะต.
*/
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()
ืืขืจืืคึฟื ื ืึธื ืื ืึทืก ืืืฉืขื ืขืจืืืฅ ืึท ืืขืฉืขืขื ืืฉ 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()
ืืขืจืืคึฟื ื ืึธื ืื ืึทืก ืืืฉืขื ืขืจืืืฅ ืึท ืืขืฉืขืขื ืืฉ EPOLLIN
, ืืื ืืขื ืคืึทื ืืืึทืืฉ ืึทื ืื ืงืฉืจ ืจืขืืืกืืจืืจื on_accept()
, ืืจืืื ืฆื ืืึทืงืืืขื ืืึทืื.
on_recv()
ืืืืขื ื ืืึทืื ืคืื ืื ืงืฉืจ ืืื ืื ืืืืคึผ ืืขืื ืืื ืืึธืจ ืืืงืืืขื, ืืื ืขืก ืจืขืืืฉืืกืืขืจื ืึท ืืึทื ืืืขืจ on_send()
ืฆื ืฉืืงื ืึท ืืืืคึผ ืขื ืืคืขืจ. ืืืื ืืขืจ ืงืืืขื ื ืืจืืืงืก ืื ืงืฉืจ, ืื ืืึธืืขื ืืื ืืขืจืขืืืกืืจืืจื ืืื ืคึฟืึทืจืืึทืื ื ืืฆื 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()
ืืขืจืืคึฟื ื ืึธื ืื ืึทืก ืืืฉืขื ืขืจืืืฅ ืึท ืืขืฉืขืขื ืืฉ EPOLLOUT
, ืืืึทืืฉ ืึทื ืื ืงืฉืจ ืจืขืืืกืืจืืจื on_recv()
, ืืจืืื ืฆื ืฉืืงื ืืึทืื. ืื ืคึฟืื ืงืฆืืข ืกืขื ืื ืึท ืืืืคึผ ืขื ืืคืขืจ ืืื HTML ืืื ืึท ืืืื ืฆื ืืขื ืงืืืขื ื ืืื ืืขืืึธืื ืขื ืืขืจืื ืืขื ืื ืืขืฉืขืขื ืืฉ ืืึทื ืืืขืจ ืฆืืจืืง ืฆื 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()
ืืืจ ืฉืึทืคึฟื ืึทื ืืื / ืึธ ืจืขืึทืงืืึธืจ ื ืืฆื 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 ืจืขืึทืงืืึธืจ ืงืขื ืขื ืืืื ืืืฉืืคื ืืื ืืึทืืื ืืขืจ ืคึฟืขืืขื, ืืื ืืขืจืืื ื ืืฆื ืึทืืข ืงืคึผื ืงืึธืจืขืก. ืืื ืก ืฉืืขืื ืืขื ืฆืืืึทื ื ืืื ืคืืจ:
ืืืืึทืื 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 ืืื ืื ืืืืฃ ืื ื ืืืขืจ ืคืื ืงืึทื ืขืงืฉืึทื ื:
ืืืจ ืืขื ืึทื ื ืึธื ืึท ืคึผืึธืจ ืคืื ืืื ืืขืจื ืงืึทื ืขืงืฉืึทื ื, ืื ื ืืืขืจ ืคืื ืคึผืจืึทืกืขืกื ืจืืงืืืขืก ืคึฟืึทืจ ืืืืืข ืกืขืจืืืขืจืก ืคืึทืื ืฉืืจืฃ (ืืื ืื ืืืืื-ืืจืขืืื ืืืขืจืกืืข ืืึธืก ืืื ืืขืจ ืืืืขืจืงื). ืืื ืืึธืก ืฉืืึทืืืช ืฆื ืื ืืืคึผืืึทืืขื ืืืืฉืึทื ืคืื Linux TCP / IP ืึธื ืืืืื? ืคืืื ืคืจืื ืฆื ืฉืจืืึทืื ืืืื ืึทืกืึทืืคึผืฉืึทื ื ืืืขืื ืืขื ื ืึทืืืจ ืคืื ืื ืืจืึทืคืืง ืืื ืึธืคึผืืืืืืึทืืืึธื ืก ืคึฟืึทืจ ืืืืื-ืืจืขืืื ืืื ืืืื-ืืจืขืืขื ืึธืคึผืฆืืขืก ืืื ืื ืืึทืืขืจืงืื ืืขื.
ืืื
ืืืกืึทืืืืึทื ืืืืืฉืื ืคืื ืืื / ืึธ ืจืขืึทืงืืึธืจ
ืืืจ ืืึทืจืคึฟื ืฆื ืคึฟืึทืจืฉืืืื ืึทื ืื I / O ืจืขืึทืงืืึธืจ ืืื ื ืืฉื ืึธื ืืืื ืืืกืึทืืืืึทื ืืืืืฉืื, ื ืืืืื:
- ื ืืฆื ืึทื ืืื / ืึธ ืจืขืึทืงืืึธืจ ืืื ืึท ืืึทืืื-ืืจืขืืื ืกืืืืืืข ืืื ืขืคึผืขืก ืืขืจ ืฉืืืขืจ, ืืืืึทื ืืืจ ืืืขื ืืึธืื ืฆื ืืึทื ืืืึทืื ืคืืจื ืื ืคืืึธืื.
- ืคืืจ ืืืืืื ืึทื ืืื ืจืืึฟ ืคืืื ืื ืืึทืกืข ืืื ื ืื-ืืื ืืืจ, ืืืึธืก ืงืขื ืขื ืคืืจื ืฆื ืืืื ืคืึธืืขื ืืึธืืื ื ืืฉืขืช ืื ืืขืจื ืืื ืคืึทืจื ืืืขื ืืื ืึทืจืืขื.
- ืืืื ืืืื ืขืจ ืืขืฉืขืขื ืืฉ ืืึทื ืืืขืจ ืืืึทืงืก ืึท ืคืึธืืขื, ืืขืจ ืกืืกืืขื ืกืขืืขืงืืึธืจ ืืื ืืืขื ืืืื ืคืึทืจืฉืคึผืึทืจื, ืืืึธืก ืงืขื ืขื ืคืืจื ืฆื ืฉืืืขืจ-ืฆื-ืืขืคืื ืขื ืืึทืื.
ืกืึทืืืื ืื ืคึผืจืึธืืืขืืก
ืกืึธืฃ
ืืึธืก ืืื ืืื ืืื ืืืขืจ ื ืกืืขื ืคืื ืืขืึธืจืืข ืืืืื ืืื ืื ืคึผืจืึธืคืืืขืจ ืืืกืืึทืืขืจื ืืื ืงืืืขื ืฆื ืึท ืกืืฃ.
ืืืจ ืืึธื ื ืืฉื ืืืืื ืขื ืืืืฃ ืืขื, ืืืืึทื ืขืก ืืขื ืขื ืคืืืข ืื ืืขืจืข ืืืืึทื ืืฉืืงืึทืืืข ืึทืคึผืจืึธืืืฉืื ืฆื ืฉืจืืืื ื ืขืฅ ืืืืืืืืืจื ืืื ืคืึทืจืฉืืืขื ืข ืืขืืืขืืก ืคืื ืงืึทื ืืืื ืืึทื ืก ืืื ืืืืงืืึทื. ืืฉืืงืึทืืืข, ืืื ืืืื ืืืื ืื ื, ืืื ืงืก ืืขื ืขื ืืขืืขืื ืืื ืื.
ืืื ืืืืึทืืขืจ ืฆืืึทื!
ืืฉืืงืึทืืืข ืคืจืืืขืงืื
- ืกื
ืืฉืึทืืืขืจ
ืืืึธืก ืึทื ืืขืจืฉ ืฆื ืืืืขื ืขื?
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