0Pricing
C Academy · บทเรียน

ตั้งค่า epoll

สร้างและลงทะเบียนชุด epoll

ตั้งค่า epoll เป็นบทเรียน C Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C Academy มีบทเรียนทั้งหมด 4 บทเรียน

การสร้างอินสแตนซ์ epoll

ทุกอย่างเริ่มต้นที่อินสแตนซ์ epoll ซึ่งเป็นตัวบอกไฟล์เช่นกัน ให้สร้างด้วย epoll_create1()

อาร์กิวเมนต์คือฟิลด์แฟล็ก ให้ส่ง 0 เพื่อใช้ลักษณะการทำงานเริ่มต้น หรือส่ง EPOLL_CLOEXEC เพื่อปิดตัวบอกไฟล์โดยอัตโนมัติเมื่อข้ามผ่าน exec() ค่า fd ที่ส่งคืนมาคือค่าที่คุณต้องส่งให้การเรียก epoll อื่น ๆ ทุกครั้ง

int epfd = epoll_create1(EPOLL_CLOEXEC);
if (epfd == -1) { perror("epoll_create1"); exit(1); }

epoll_create1 เทียบกับ epoll_create

epoll_create(int size) รุ่นเก่ารับคำใบ้เกี่ยวกับขนาด แต่ขณะนี้เคอร์เนลไม่สนใจค่านี้แล้ว สิ่งเดียวที่กำหนดคือค่าต้องเป็นบวก

ควรเลือกใช้ epoll_create1() เพราะรับแฟล็กแทนขนาดที่ไม่มีความหมาย และให้คุณขอใช้ EPOLL_CLOEXEC ได้แบบอะตอมิก จึงไม่ต้องเรียก fcntl() แยกต่างหาก

/* legacy form, size arg ignored by kernel */
int epfd = epoll_create(1);

โครงสร้าง epoll_event

ทั้งสิ่งที่สนใจและผลลัพธ์จะแสดงผ่าน struct epoll_event โครงสร้างนี้มีบิตแมสก์ events และยูเนียน data

ยูเนียน data เก็บสิ่งใด ๆ ที่คุณต้องการให้ส่งคืนเมื่อเหตุการณ์เกิดขึ้น โดยทั่วไปมักเป็น data.fd แต่ยังอาจเป็น data.ptr ที่ชี้ไปยังออบเจ็กต์การเชื่อมต่อที่คุณจัดสรรไว้ได้ด้วย

struct epoll_event ev;
ev.events = EPOLLIN;
ev.data.fd = listen_fd;

การลงทะเบียนด้วย EPOLL_CTL_ADD

epoll_ctl() ใช้จัดการรายการสิ่งที่สนใจ ให้ใช้การดำเนินการ EPOLL_CTL_ADD เพื่อเริ่มเฝ้าดูตัวบอกไฟล์

คุณต้องส่ง fd ของ epoll การดำเนินการ fd เป้าหมาย และพอยน์เตอร์ไปยัง epoll_event ของคุณ หลังจากนั้น epoll จะรายงานความพร้อมใช้งานของตัวบอกไฟล์นั้น

struct epoll_event ev = { .events = EPOLLIN, .data.fd = listen_fd };
if (epoll_ctl(epfd, EPOLL_CTL_ADD, listen_fd, &ev) == -1)
    perror("epoll_ctl: add");

แฟล็กเหตุการณ์: EPOLLIN และ EPOLLOUT

มาสก์ events ระบุสิ่งที่คุณสนใจ EPOLLIN หมายความว่าตัวบอกไฟล์พร้อมอ่าน ส่วน EPOLLOUT หมายความว่าพร้อมเขียน

โดยทั่วไปคุณจะเฝ้าดู EPOLLIN บนซ็อกเก็ตที่รอรับการเชื่อมต่อ (เพื่อรับการเชื่อมต่อ) และบนซ็อกเก็ตของไคลเอ็นต์ (เพื่ออ่านข้อมูล) ให้เพิ่ม EPOLLOUT เฉพาะเมื่อมีข้อมูลในบัฟเฟอร์ที่ยังส่งไม่ครบ

ev.events = EPOLLIN | EPOLLOUT;

แฟล็กข้อผิดพลาดและการตัดการเชื่อมต่อ

เคอร์เนลจะรายงานเงื่อนไขบางอย่างเสมอ แม้ว่าคุณจะไม่ได้ร้องขอก็ตาม ได้แก่ EPOLLERR สำหรับข้อผิดพลาด EPOLLHUP สำหรับการตัดการเชื่อมต่อ และ EPOLLRDHUP สำหรับการปิดการเชื่อมต่อครึ่งหนึ่งโดยคู่สื่อสาร

ให้ตรวจสอบสิ่งเหล่านี้ในตัวจัดการของคุณ การเพิกเฉยต่อ EPOLLHUP บนซ็อกเก็ตที่ตายแล้วจะทำให้ลูปเหตุการณ์ทำงานวนซ้ำโดยเปล่าประโยชน์

if (ev.events & (EPOLLERR | EPOLLHUP)) {
    close(ev.data.fd);
    continue;
}

การแก้ไขสิ่งที่สนใจด้วย EPOLL_CTL_MOD

เมื่อลงทะเบียนตัวบอกไฟล์แล้ว คุณสามารถเปลี่ยนมาสก์เหตุการณ์ได้โดยไม่ต้องนำตัวบอกไฟล์ออก ให้ใช้ EPOLL_CTL_MOD

รูปแบบที่ใช้กันทั่วไปคือ การเชื่อมต่อจะเฝ้าดูเฉพาะ EPOLLIN ตามปกติ จากนั้นเปลี่ยนเป็น EPOLLIN | EPOLLOUT เมื่อบัฟเฟอร์ส่งข้อมูลเต็ม และเปลี่ยนกลับอีกครั้งเมื่อส่งข้อมูลในบัฟเฟอร์ออกหมดแล้ว

ev.events = EPOLLIN | EPOLLOUT;
ev.data.fd = conn_fd;
epoll_ctl(epfd, EPOLL_CTL_MOD, conn_fd, &ev);

การนำออกด้วย EPOLL_CTL_DEL

เมื่อการเชื่อมต่อปิดลง ให้หยุดเฝ้าดูด้วย EPOLL_CTL_DEL อาร์กิวเมนต์ epoll_event สุดท้ายจะถูกละเลย และในเคอร์เนลสมัยใหม่อาจเป็น NULL ได้

โปรดทราบว่าเมื่อปิดตัวบอกไฟล์ ระบบจะนำตัวบอกไฟล์นั้นออกจากรายการสิ่งที่สนใจของ epoll โดยอัตโนมัติ แต่การลบออกอย่างชัดเจนก่อนปิดจะช่วยให้การจัดการข้อมูลของคุณชัดเจน

epoll_ctl(epfd, EPOLL_CTL_DEL, conn_fd, NULL);
close(conn_fd);

แบบตรวจระดับเทียบกับแบบตรวจขอบ

โดยค่าเริ่มต้น epoll ใช้การตรวจระดับ: ตราบใดที่ตัวบอกไฟล์ยังอ่านได้ ทุกการเรียก epoll_wait() จะรายงานตัวบอกไฟล์นั้น วิธีนี้รองรับข้อผิดพลาดได้ดีและใช้งานง่าย

ให้เพิ่มแฟล็ก EPOLLET เพื่อใช้โหมดการตรวจขอบ ระบบจะแจ้งเตือนเฉพาะเมื่อสถานะความพร้อมใช้งานเปลี่ยน ดังนั้นคุณต้องอ่านข้อมูลจากซ็อกเก็ตออกจนหมดในลูปจนกว่าจะได้ EAGAIN

ev.events = EPOLLIN | EPOLLET;  /* edge-triggered */
epoll_ctl(epfd, EPOLL_CTL_ADD, conn_fd, &ev);

การจัดเก็บพอยน์เตอร์บริบท

แทนที่จะใช้ data.fd คุณสามารถจัดเก็บ data.ptr ที่ชี้ไปยังโครงสร้างสำหรับการเชื่อมต่อแต่ละรายการได้ เมื่อเหตุการณ์เกิดขึ้น คุณจะได้พอยน์เตอร์นั้นกลับมาโดยตรง โดยไม่ต้องใช้ตารางค้นหา

เพียงจำไว้ว่านี่เป็นยูเนียน หากคุณกำหนดค่า data.ptr แล้ว คุณจะไม่สามารถอ่าน data.fd จากเหตุการณ์เดียวกันได้

struct conn *c = malloc(sizeof *c);
c->fd = conn_fd;
ev.events = EPOLLIN;
ev.data.ptr = c;
epoll_ctl(epfd, EPOLL_CTL_ADD, conn_fd, &ev);

การล้างทรัพยากร

อินสแตนซ์ epoll เป็นเพียงตัวบอกไฟล์ ดังนั้นให้คืนทรัพยากรด้วย close() เมื่อเซิร์ฟเวอร์ปิดการทำงาน

การปิด fd ของ epoll จะคืนรายการสิ่งที่สนใจของเคอร์เนล ซ็อกเก็ตที่ยังเปิดและอยู่ภายใต้การเฝ้าดูจะยังคงเปิดอยู่ คุณต้องปิดซ็อกเก็ตเหล่านั้นแยกต่างหากเพื่อคืนทรัพยากร

close(epfd);

ตรวจสอบความเข้าใจอย่างรวดเร็ว

ทดสอบความเข้าใจของคุณเกี่ยวกับส่วนติดต่อการตั้งค่า epoll

สรุปทบทวน

คุณสร้างอินสแตนซ์ด้วย epoll_create1() จากนั้นจัดการสิ่งที่สนใจผ่าน epoll_ctl() โดยใช้ ADD, MOD และ DEL แต่ละ struct epoll_event จะมีมาสก์ events และยูเนียน data

เลือกการตรวจระดับเพื่อความเรียบง่าย หรือเลือก EPOLLET เพื่อประสิทธิภาพแบบตรวจขอบ ในหัวข้อถัดไป เราจะขับเคลื่อนส่วนประกอบเหล่านี้ด้วยลูปเหตุการณ์

คำถามที่พบบ่อย

บทเรียน “ตั้งค่า epoll” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ตั้งค่า epoll” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “ตั้งค่า epoll”

สร้างและลงทะเบียนชุด epoll คุณปฏิบัติ C Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน C Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “ตั้งค่า epoll” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน C Academy นี้ได้ไหม

ได้ บทเรียน C Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. I/O แบบบล็อกเทียบกับไม่บล็อก
  2. ตั้งค่า epoll
  3. ลูปเหตุการณ์
  4. เซิร์ฟเวอร์สะท้อนกลับอย่างง่าย
← กลับไปที่ C Academy