Nếu máy tính bắt đầu đếm từ 0, tại sao quá trình init có pid bằng 1?


27

Không có nhiều để đặt ở đây trong cơ thể.


18
pid0 có một ý nghĩa đặc biệt cho kill(2)cuộc gọi hệ thống trong đó nó có nghĩa là chính tôi và ít nhất waitpid(2)nó có nghĩa là bất kỳ quy trình nào trong nhóm quy trình của tôi . Chưa kể rằng fork()trở về 0có nghĩa là chúng ta đang ở trong đứa trẻ.
Stéphane Chazelas

1
bạn nên đăng bài này như một câu trả lời
Jonathan Muller

3
Không làm cho các cờ được tự động thiết lập trên hầu hết các thanh ghi trạng thái của CPU khi được nạp vào một thanh ghi, cho phép một nhánh được thực hiện trên nó mà không cần so sánh / kiểm tra cụ thể về nó. Do đó, nó được sử dụng rất nhiều như một giá trị "sentinel", nghĩa là một giá trị có nghĩa là "không hợp lệ", "kết thúc dữ liệu" hoặc "trường hợp đặc biệt" ở đây. Vì vậy, mặc dù các máy tính bắt đầu đếm từ 0, sẽ có nhiều trường hợp trong đó 1 là giá trị hợp lệ đầu tiên cho ứng dụng hoặc cấu trúc dữ liệu được đề cập.
LawrenceC

4
Một lưu ý phụ: Máy tính không bắt đầu đếm từ 0. Nhiều ngôn ngữ lập trình và tôi tin rằng tất cả các ngôn ngữ máy đều sử dụng offset, trong đó các ngôn ngữ khác (và hầu hết con người) sử dụng các chỉ mục, nhưng, không có vấn đề gì, đếm là đếm. Một mảng có hai phần tử có hai phần tử (đếm chúng), bất kể ngôn ngữ của bạn đề cập đến chúng bằng offset hay theo chỉ mục.
jthill

đây có thể là một trường hợp đối lập với các mô hình lập trình cơ bản: trọng lực của lập trình viên đối với các giá trị cờ đặc biệt (không, âm) vượt qua mức độ thấp hơn của một hệ thống đánh số dựa trên số không.
michael

Câu trả lời:


29

Các quy trình cần phải có cha mẹ (PPID). Hạt nhân, mặc dù không phải là một quy trình thực, tuy nhiên vẫn đang tạo thủ công một số quy trình thực như ít nhất là init và tự cung cấp ID tiến trình 0. Tùy thuộc vào hệ điều hành, nó có thể hoặc không được hiển thị dưới dạng một quy trình trong psđầu ra nhưng luôn được hiển thị dưới dạng PPID:

ví dụ: trên Linux:

$ ps -ef|head
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 09:09 ?        00:00:00 /sbin/init
root         2     0  0 09:09 ?        00:00:00 [kthreadd]
root         3     2  0 09:09 ?        00:00:00 [ksoftirqd/0]
...

trên Solaris:

$ ps -ef|head
     UID   PID  PPID   C    STIME TTY         TIME CMD
    root     0     0   0   Oct 19 ?           0:01 sched
    root     5     0   0   Oct 19 ?          11:20 zpool-rpool1
    root     1     0   0   Oct 19 ?           0:13 /sbin/init
    root     2     0   0   Oct 19 ?           0:07 pageout
    root     3     0   1   Oct 19 ?         117:10 fsflush
    root   341     1   0   Oct 19 ?           0:15 /usr/lib/hal/hald --daemon=yes
    root     9     1   0   Oct 19 ?           0:59 /lib/svc/bin/svc.startd
...

Cũng lưu ý rằng pid 0(và -1và các giá trị tiêu cực khác cho rằng vấn đề) có ý nghĩa khác nhau tùy thuộc vào những gì chức năng sử dụng chúng thích kill, forkwaitpid.

Cuối cùng, trong khi initquy trình được đưa ra theo truyền thống #1, điều này không còn xảy ra khi ảo hóa cấp độ hệ điều hành được sử dụng như các vùng Solaris, vì có thể có nhiều hơn một hoạt initđộng:

$ ps -ef|head
     UID   PID  PPID   C    STIME TTY         TIME CMD
    root  4733  3949   0 11:07:25 ?           0:26 /lib/svc/bin/svc.configd
    root  4731  3949   0 11:07:24 ?           0:06 /lib/svc/bin/svc.startd
    root  3949  3949   0 11:07:14 ?           0:00 zsched
  daemon  4856  3949   0 11:07:46 ?           0:00 /lib/crypto/kcfd
    root  4573  3949   0 11:07:23 ?           0:00 /usr/sbin/init
  netcfg  4790  3949   0 11:07:34 ?           0:00 /lib/inet/netcfgd
    root  4868  3949   0 11:07:48 ?           0:00 /usr/lib/pfexecd
    root  4897  3949   0 11:07:51 ?           0:00 /usr/lib/utmpd
  netadm  4980  3949   0 11:07:54 ?           0:01 /lib/inet/nwamd

5

Có hai tác vụ với ID tiến trình được phân biệt đặc biệt: trình trao đổi hoặc lịch biểu có ID tiến trình 0 và chịu trách nhiệm phân trang, như jlliagre đưa vào các ví dụ trước đó và thực sự là một phần của kernel chứ không phải là quy trình chế độ người dùng thông thường.

ID tiến trình 1 thường là quá trình init chịu trách nhiệm chính cho việc khởi động và tắt hệ thống. Ban đầu, quy trình ID 1 không được dành riêng cho init bởi bất kỳ biện pháp kỹ thuật nào: đơn giản là ID này là kết quả tự nhiên của quá trình đầu tiên được gọi bởi kernel. Các hệ thống Unix gần đây thường có các thành phần hạt nhân bổ sung hiển thị dưới dạng 'quy trình', trong trường hợp đó, PID 1 được tích cực dành riêng cho quy trình init để duy trì tính nhất quán với các hệ thống cũ.


4

Nói chung, 0 thường được sử dụng để biểu thị một 'tham chiếu null'. Điều này có nghĩa là mặc dù giá trị 0 tồn tại, bạn có thể không sử dụng nó vì bạn muốn số 0 biểu thị một giá trị đặc biệt.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.