Process và Thread — từ nền tảng hệ điều hành đến Java
Process khác thread ra sao: process được HĐH cô lập không gian địa chỉ, thread chia sẻ heap nhưng giữ riêng stack. Vì sao thread nhẹ hơn và context switch rẻ hơn.
TL;DR: Process là chương trình đang trong trạng thái thực thi — có không gian địa chỉ, tài nguyên và ngữ cảnh riêng, được hệ điều hành cô lập để nhiều chương trình chạy chung một máy mà không phá nhau. Thread là dòng thực thi bên trong process: nhiều thread chia sẻ heap, code section và file handles, nhưng giữ riêng stack, program counter và register set. Chia sẻ heap khiến thread nhẹ hơn process và phối hợp dữ liệu dễ hơn, nhưng cũng là cội nguồn của race condition. Tạo một thread rẻ hơn tạo một process, và context switch giữa hai thread cùng process cũng rẻ hơn giữa hai process, vì phần lớn tài nguyên đã được dùng chung sẵn.
1. Vì sao hệ điều hành cần khái niệm process?
Máy tính đời đầu chỉ chạy một chương trình tại một thời điểm, nắm gần như toàn quyền CPU, bộ nhớ và phần cứng — dùng tài nguyên rất kém (lúc chờ I/O thì CPU bỏ không) và bắt lập trình viên bận tâm quá nhiều chi tiết cấp thấp. Hệ thống hiện đại thì bạn vừa mở trình duyệt, vừa soạn tài liệu, vừa nghe nhạc: hệ điều hành phải kiểm soát ai được dùng CPU, ai được cấp bộ nhớ, ai truy cập I/O, và quan trọng nhất, chương trình này không được tùy tiện ảnh hưởng chương trình khác. Từ nhu cầu quản lý, cô lập và điều phối đó, process ra đời.
2. Process: chương trình khi bước vào trạng thái thực thi
2.1 Vì sao hệ điều hành cần nhiều process?
Ba động lực dẫn đến việc cho nhiều chương trình cùng thực thi:
- Tận dụng tài nguyên. Lúc một process chờ I/O, hệ điều hành chuyển CPU sang process khác thay vì để CPU rảnh.
- Tính công bằng. Hệ điều hành chia thời gian CPU thành các lát — time slices — xoay vòng cho nhiều process, nên chúng có cảm giác chạy đồng thời dù một core tại một thời điểm chỉ thực thi một dòng lệnh. (SMT/hyper-threading cho một core vật lý chạy hai luồng phần cứng xen kẽ, nhưng bức tranh "một core — một dòng lệnh" vẫn đúng để suy luận scheduling.)
- Sự tiện lợi. Nhiều chương trình nhỏ, mỗi cái một nhiệm vụ, dễ bảo trì hơn một khối khổng lồ — cũng là tư tưởng chia nhỏ trách nhiệm của thiết kế hệ thống.
2.2 Process là gì?
Process là một chương trình đang trong trạng thái thực thi — đơn vị công việc cơ bản để hệ điều hành quản lý các hoạt động đang diễn ra. Nó không chỉ gồm mã lệnh; trạng thái hiện tại của nó gồm:
- Program counter — instruction tiếp theo sẽ được thực thi.
- Processor registers — giá trị trung gian và trạng thái xử lý của CPU.
- Không gian địa chỉ bộ nhớ — nơi lưu mã lệnh, dữ liệu, heap và stack.
- Các tài nguyên hệ điều hành — file đang mở, quyền bảo mật, socket, signal.
Các process được cô lập: một process không thể truy cập trực tiếp vùng nhớ hay tài nguyên nội bộ của process khác. Đó là lý do hệ điều hành hiện đại chạy nhiều chương trình cùng lúc mà vẫn ổn định — một chương trình lỗi thì chỉ process đó chết, không kéo sập hệ thống hay phá dữ liệu của process khác. Muốn giao tiếp, process phải dùng cơ chế giao tiếp liên tiến trình — inter-process communication: socket, signal handler, shared memory, semaphore hoặc file.
Hai process là hai "căn nhà" tách biệt, mỗi nhà đủ code, data, heap, stack riêng — muốn nói chuyện phải đi qua "đường công cộng" IPC.
flowchart LR
subgraph PA["Process A"]
direction TB
CA["Code + Data"]
HA["Heap riêng"]
SA["Stack riêng"]
end
subgraph PB["Process B"]
direction TB
CB["Code + Data"]
HB["Heap riêng"]
SB["Stack riêng"]
end
PA <-. "IPC: socket, pipe,<br/>shared memory, signal" .-> PBMột phân biệt rất quan trọng: program không phải là process. Program là thực thể thụ động — passive entity — file chứa danh sách instruction nằm trên đĩa (executable file). Process là thực thể chủ động — active entity — có program counter, trạng thái thực thi, không gian bộ nhớ và tài nguyên được cấp phát. Program trở thành process khi executable file được nạp vào bộ nhớ và bắt đầu thực thi.
2.3 Bố cục bộ nhớ của một process
- Text section: mã thực thi — executable code.
- Data section: các biến toàn cục — global variables.
- Heap section: vùng nhớ cấp phát động trong thời gian chạy.
- Stack section: dữ liệu tạm thời khi gọi hàm — tham số, địa chỉ trả về, biến cục bộ.
Text và data section có kích thước tương đối cố định; stack và heap co giãn động. Mỗi lần gọi hàm, một activation record — bản ghi kích hoạt, chứa tham số, biến cục bộ và địa chỉ trả về — được đẩy vào stack, hàm kết thúc thì lấy ra. Heap phát triển khi chương trình cấp phát bộ nhớ động; trong ngôn ngữ có garbage collector như Java, bộ gom rác thu hồi heap khi object không còn reachable. Stack và heap phát triển về phía nhau, nhưng runtime phải đảm bảo chúng không chồng lấn.
3. Thread
3.1 Từ process đến thread
Ở mô hình process truyền thống, mỗi process chỉ có một luồng điều khiển — single thread of control — đủ tốt khi chương trình làm một việc tại một thời điểm. Nhưng một chương trình thường gồm nhiều hoạt động bán độc lập (xử lý giao diện, đọc file, gửi request mạng, tính toán nền); ép tất cả qua một dòng thực thi thì chương trình kém phản hồi và phí tài nguyên. Thread giải quyết điều đó bên trong một process: nhiều dòng điều khiển cùng tồn tại, nhiều phần của cùng chương trình tiến triển gần như đồng thời. Nếu process là cách hệ điều hành cô lập các chương trình đang chạy, thì thread là cách một process tự chia nhỏ dòng thực thi của mình.
Thread giúp chương trình linh hoạt hơn, phản hồi tốt hơn, khai thác parallelism tốt hơn. Đổi lại: các thread chia sẻ cùng bộ nhớ, nên truy cập dữ liệu dùng chung phải được phối hợp cẩn thận bằng các cơ chế synchronization.
3.2 Thread là gì?
Thread là đơn vị thực thi cơ bản bên trong một process; một process có thể có một hoặc nhiều thread.
Mỗi thread giữ riêng: thread ID, program counter, register set, stack. Các thread cùng process chia sẻ: code section, data section, heap, open files, signals và các tài nguyên OS khác của process. Chúng cùng "ở chung nhà" — khác hẳn hai process cô lập ở sơ đồ trên.
Thread đôi khi được gọi là lightweight process — tiến trình nhẹ — vì nó cũng là đơn vị thực thi được lập lịch, nhưng nhẹ hơn process do chia sẻ nhiều tài nguyên. Scheduler của hệ điều hành hiện đại lập lịch theo thread, nên với CPU scheduling, thread mới là đơn vị quan trọng hơn process.
3.3 Vì sao cần thread?
- Khai thác tốt hơn tài nguyên CPU. Một thread chờ I/O thì thread khác vẫn chạy tiếp: server đang chờ database cho request này vẫn xử lý được request khác.
- Tăng tính phản hồi. Một thread lo UI, thread khác chạy tác vụ nền, nên ứng dụng không "đơ" khi xử lý dữ liệu nặng.
- Chia nhỏ chương trình tự nhiên hơn. Trình duyệt tách thread cho rendering, network, JavaScript execution, background task.
- Khai thác parallelism trên multicore. Nhiều thread cùng process chạy đồng thời trên nhiều CPU core — cơ sở tăng hiệu năng cho chương trình parallel.
- Concurrency = nhiều công việc cùng tiến triển trong cùng một khoảng thời gian.
- Parallelism = nhiều công việc thực sự chạy cùng lúc trên nhiều core.
Thread hỗ trợ cả hai, nhưng có đạt parallelism thực sự hay không còn tuỳ phần cứng, hệ điều hành, runtime và bản chất workload.
4. Liên hệ các bài khác
- Mô hình ánh xạ thread — bài này nói thread là gì; bài kế trả lời một Java thread thực sự ánh xạ xuống đâu trong hệ điều hành (ba mô hình user→kernel thread) và vì sao platform thread không hề rẻ.
- Thread API và vòng đời — sau khi biết thread là gì, bài này dạy cách tạo, chờ và dừng một thread đúng cách, và vì sao không thể kill thread từ bên ngoài.
- Thread Safety — chính việc nhiều thread dùng chung heap (điểm cốt lõi của bài này) là cội nguồn của race condition; bài 03 mổ xẻ vấn đề đó và bốn chiến lược xử lý.
5. 📚 Deep Dive
Spec / reference:
- Java SE 21 —
java.lang.Thread— API chính thức của lớpThread: vòng đời, daemon, priority, ghi chú platform vs virtual thread. - Operating Systems: Three Easy Pieces — Processes — chương Process và Thread của giáo trình OSTEP (miễn phí): cô lập không gian địa chỉ, activation record, và vì sao thread nhẹ hơn process.
Ghi chú: Đọc chương "Abstraction: The Process" của OSTEP để thấy vì sao program (thụ động trên đĩa) khác process (chủ động trong bộ nhớ), và cách OS ảo hoá CPU cho nhiều process.
6. Tóm tắt
- Process là chương trình đang thực thi: không gian địa chỉ, trạng thái và tài nguyên riêng, được cô lập; muốn nói chuyện phải qua IPC. Program là thực thể thụ động trên đĩa, process là thực thể chủ động trong bộ nhớ.
- Thread là dòng thực thi bên trong process: chung code, data, heap, open files — riêng thread ID, program counter, register set, stack.
- Chia sẻ heap khiến thread nhẹ và phối hợp dữ liệu dễ, nhưng nhiều thread cùng sửa một dữ liệu mà thiếu synchronization thì sinh race condition.
- Tạo thread và context switch giữa các thread cùng process rẻ hơn process vì phần lớn tài nguyên đã dùng chung sẵn — nhưng vẫn không miễn phí, nên tạo hàng chục nghìn thread vẫn là ý tưởng tồi.
Biết process và thread khác nhau thế nào rồi, câu hỏi kế tiếp là một Java thread thực sự ánh xạ xuống đâu trong hệ điều hành — bài 01b mổ ba mô hình ánh xạ user thread lên kernel thread.
7. Tự kiểm tra
Q1Phân biệt program và process. Vì sao chạy cùng một chương trình hai lần lại là hai process khác nhau?▸
Program là thực thể thụ động — một file chứa danh sách instruction nằm trên đĩa (executable file). Process là thực thể chủ động — có program counter, trạng thái thực thi, không gian bộ nhớ riêng và tập tài nguyên do OS cấp phát.
Chạy cùng một chương trình hai lần tạo ra hai process vì mỗi lần nạp executable vào bộ nhớ, OS dựng một không gian địa chỉ và tập tài nguyên riêng. Chúng có thể dùng chung text section, nhưng data, heap và stack là độc lập — như mở hai cửa sổ trình duyệt cùng lúc.
Q2Hai thread cùng một process dùng chung những gì, giữ riêng những gì?▸
Chung: code section, data section, heap (mọi object), open files, signals và các tài nguyên OS thuộc process.
Riêng: thread ID, program counter, register set và stack (biến cục bộ).
Vì stack riêng nên biến cục bộ của thread này thread khác không chạm tới — mặc nhiên an toàn. Vì heap chung nên object được chia sẻ; đây vừa là sức mạnh (chia dữ liệu không cần copy) vừa là cội nguồn của race condition khi thiếu synchronization.
Q3Khi một thread gọi hàm rồi hàm kết thúc, điều gì xảy ra trên stack của nó? Và vì sao biến cục bộ của thread này thread khác không nhìn thấy?▸
Mỗi lần gọi hàm, một activation record (chứa tham số, biến cục bộ và địa chỉ trả về) được đẩy vào stack của thread; khi hàm kết thúc, record đó bị lấy ra (pop), trả lại vùng nhớ. Đó là lý do biến cục bộ chỉ sống trong phạm vi một lời gọi hàm.
Mỗi thread có stack riêng, không chia sẻ. Nên biến cục bộ nằm trên stack của một thread thì thread khác không có đường truy cập tới — đây là dạng an toàn "miễn phí" (thread confinement) không cần synchronization, khác hẳn object trên heap dùng chung.
Q4Vì sao tạo một thread mới rẻ hơn tạo một process mới, và context switch giữa hai thread cùng process rẻ hơn giữa hai process?▸
Khi tạo process, OS phải dựng cả một không gian địa chỉ mới: bảng ánh xạ bộ nhớ, vùng code/data/heap, tập tài nguyên (file handles, credentials). Tạo thread trong process có sẵn thì phần tốn kém đó đã tồn tại — OS chỉ cấp thêm một stack và cấu trúc quản lý thread, còn lại dùng chung.
Context switch giữa hai thread cùng process chỉ swap program counter, register set, stack pointer. Switch giữa hai process còn phải đổi cả ánh xạ bộ nhớ, khiến cache dịch địa chỉ (TLB) và cache dữ liệu mất tính nóng — chi phí gián tiếp này thường lớn hơn cả swap register.
Q5Máy có 4 CPU core nhưng JVM đang chạy 200 thread. Đây là concurrency hay parallelism? Tối đa bao nhiêu thread thực sự chạy cùng lúc?▸
Cả hai, ở hai mức khác nhau. Tại một thời điểm, tối đa 4 thread thực sự thực thi song song — mỗi core một thread (bỏ qua SMT): đó là parallelism, và phần cứng là trần của nó. 196 thread còn lại đang chờ tới lượt hoặc chờ I/O; scheduler chia time slice xoay vòng nên trong một khoảng đủ dài cả 200 thread đều tiến triển — đó là concurrency.
Hệ quả: với workload CPU-bound, tạo nhiều thread hơn số core không nhanh hơn mà chỉ tốn thêm context switch; nhiều thread hơn số core chỉ có lợi khi phần lớn thread dành thời gian chờ I/O.
Bài tiếp theo: Mô hình ánh xạ thread — user, kernel và vì sao platform thread không rẻ
Bài này đáng gửi cho bạn học cùng?
Copy link đã gắn nguồn — dán group, chat, hoặc LinkedIn.
Bài này có giúp bạn hiểu bản chất không?
Hỏi đáp về bài này
Chưa có câu hỏi
Có gì chưa rõ trong bài? Đặt câu hỏi đầu tiên — câu trả lời từ cộng đồng giúp bạn (và người sau).
Đặt câu hỏi đầu tiên