Mỗi khi có một câu hỏi về blocking hoặc non-blocking calls, thì gần như đó là vấn đề xoay quanh việc xử lý quá trình input/output (I/O). Hãy tưởng tượng rằng bạn khi bạn đang lướt web (web browser hoặc một app bạn đang sử dụng là một client) thì ở đâu đó có một server đang xử lý request bạn gửi đi và sinh ra những dòng chữ mà bạn đang đọc ở đây.
Để có sự tương tác giữa client-server như vậy thì cả client và server phải thiết lập kết nối với nhau. Chúng ta sẽ không đi sâu vào mô hình 7 tầng hay là protocol stack có liên quan đến quá trình tương tác này, mà chúng ta sẽ tìm hiểu thêm về những điểm kết nối đặc biệt như sockets, cách mà client và server ràng buộc với nhau, lắng nghe và hiểu được nhau.
Có 2 cách để tổ chức I/O: blocking và non-blocking
Và quá trình I/O cũng có 2 loại: đồng bộ (synchronous) và bất đồng bộ (asynchronous )

Blocking I/O
Với blocking I/O, khi client tạo một connection request đến server thì socket chịu trách nhiệm kết nối và luồng đọc dữ liệu tương ứng sẽ bị blocked lại cho đến khi có một vài dữ liệu đã được xử lý xong xuất hiện. Những dữ liệu này được đặt ở hàng chờ network cho đến khi nào nó được đọc và sẵn sàng để xử lý. Cho đến lúc quá trình hoàn thành, server không thể làm gì thêm khác ngoài việc chờ đợi. Vì vậy, ta không thể xử lý nhiều hơn một connection trong đơn luồng. Mặc định thì TCP sockets là blocking mode.
Non-Blocking I/O
Tuy nhiên, chúng ta có cơ chế thứ hai: non-blocking – thay vì bị block mọi request sẽ được đưa lên hàng đợi ngay lập tức, xử lý và trả ra kết quả. Quá trình I/O thực sự sẽ tiến hành vào lúc khác. Chúng ta có thể kết nối với một non-blocking socket khi mà nó không có dữ liệu, kết quả trả ra sẽ là error code.
Thực ra cách này cũng không tốt lắm, nếu chương trình có một bộ dữ liệu lớn thì sẽ tốn rất nhiều tài nguyên của CPU. Chế độ này có thể sẽ không hiệu quả trong trường hợp ứng dụng phải đợi có dữ liệu trước sau đó mới thực thi một số việc khác
Bù lại chúng ta có thể thực hiện nhiều quá trình I/O khác nhau với các socket khác nhau từ cùng một luồng một cách đồng thời. Cơ chế polling readiness mechanism sẽ giúp chúng ta biết được socket nào sẵn sàng để thực hiện I/O operation mới. Dựa vào cơ chế này, mỗi khi một socket nào sẵn sàng sẽ được đưa lên hàng đợi và thực hiện, sau đó socket được chuyển sang chế độ blocking cho đến khi nó sẵn sàng để thực hiện quá trình I/O tiếp theo.