2009-11-19 29 views
179

Gần đây, tôi đã được hỏi một câu hỏi trong một cuộc phỏng vấn sự khác biệt giữa quy trình và chuỗi. Thực sự, tôi không biết câu trả lời. Tôi nghĩ trong một phút và đưa ra một câu trả lời rất kỳ lạ.Tài nguyên nào được chia sẻ giữa các luồng?

Chủ đề chia sẻ cùng một bộ nhớ, quy trình thì không. Sau khi trả lời câu hỏi này, người phỏng vấn đã cho tôi một nụ cười độc ác và sa thải những câu hỏi sau đây cho tôi:

Q. Bạn có biết các phân đoạn trong đó một chương trình được chia không?

câu trả lời của tôi: vâng (nghĩ rằng nó là một điều dễ dàng) Stack, dữ liệu, Mã, Heap

Q. Vì vậy, cho tôi biết: đó phân khúc làm chủ đề chia sẻ?

Tôi không thể trả lời câu hỏi này và kết thúc bằng cách nói tất cả.

Xin vui lòng, ai có thể trình bày câu trả lời đúng và ấn tượng cho sự khác biệt giữa quy trình và chuỗi?

+5

Chủ đề chia sẻ cùng một _address-space_ ảo, quá trình không. – Benoit

+2

bản sao có thể có của [Sự khác biệt giữa quy trình và chuỗi] (http://stackoverflow.com/questions/200469/what-is-the-difference-between-a-process-and-a-thread) – sashoalm

Trả lời

111

Bạn khá chính xác nhưng các chuỗi chia sẻ tất cả các phân đoạn ngoại trừ ngăn xếp. Chủ đề có ngăn xếp cuộc gọi độc lập, tuy nhiên bộ nhớ trong ngăn xếp luồng khác vẫn có thể truy cập được và trong lý thuyết bạn có thể giữ con trỏ vào bộ nhớ trong khung ngăn xếp cục bộ của một số luồng khác (mặc dù bạn có thể nên tìm một nơi tốt hơn để đặt bộ nhớ đó!).

+13

Phần thú vị là mặc dù các luồng có ngăn xếp cuộc gọi độc lập, bộ nhớ trong các ngăn xếp khác vẫn có thể truy cập được. –

10

Chủ đề chia sẻ mã và phân đoạn dữ liệu và heap, nhưng họ không chia sẻ ngăn xếp.

+9

Có sự khác biệt giữa "có thể truy cập dữ liệu trong ngăn xếp" và chia sẻ ngăn xếp. Những chủ đề có ngăn xếp của riêng họ mà được đẩy và xuất hiện khi họ gọi phương pháp. –

+2

Cả hai chế độ xem đều hợp lệ. Có, mỗi luồng có ngăn xếp riêng của nó theo nghĩa là có một sự tương ứng một-một giữa các chủ đề và ngăn xếp và mỗi luồng có một không gian nó sử dụng cho việc sử dụng ngăn xếp bình thường của riêng nó. Nhưng chúng cũng hoàn toàn được chia sẻ tài nguyên quy trình và nếu muốn, bất kỳ chuỗi nào cũng có thể truy cập bất kỳ ngăn xếp nào của chủ đề khác dễ dàng như chính nó. –

+0

@DavidSchwartz, tôi có thể tóm tắt điểm của bạn như sau: Mỗi luồng có ngăn xếp riêng và ngăn xếp bao gồm 2 phần - phần đầu tiên được chia sẻ giữa các luồng trước khi quá trình đa luồng và phần thứ hai được điền khi chuỗi đang sở hữu đang chạy .. Đồng ý? – FaceBro

1

Chủ đề chia sẻ heap (có một nghiên cứu về chuỗi cụ thể của luồng) nhưng việc triển khai hiện tại chia sẻ đống. (và tất nhiên mã)

5

Chủ đề chia sẻ dữ liệu và mã trong khi các quá trình không. Ngăn xếp không được chia sẻ cho cả hai.

Quy trình cũng có thể chia sẻ bộ nhớ, mã chính xác hơn, ví dụ: sau Fork(), nhưng đây là chi tiết triển khai và tối ưu hóa hệ điều hành. Mã được chia sẻ bởi nhiều tiến trình (hy vọng) sẽ được sao chép vào lần ghi đầu tiên vào mã - điều này được gọi là copy-on-write. Tôi không chắc chắn về ngữ nghĩa chính xác cho mã của chủ đề, nhưng tôi giả sử mã chia sẻ.

 
      Process Thread 

    Stack private private 
    Data private shared 
    Code private1 shared2 

Mã này là logic tin nhưng có thể được chia sẻ vì lý do hiệu suất. Tôi không chắc chắn 100%.

+0

Tôi muốn nói phân đoạn mã (phân đoạn văn bản), không giống như dữ liệu, hầu như luôn luôn chỉ đọc trên hầu hết các kiến ​​trúc. –

46

Từ Wikipedia (Tôi nghĩ rằng sẽ làm cho một câu trả lời thực sự tốt cho người phỏng vấn: P)

Chủ đề khác với truyền thống hệ điều hành đa nhiệm quá trình trong đó:

  • quá trình thường độc lập, trong khi chuỗi tồn tại dưới dạng tập hợp con của quy trình
  • mang thông tin trạng thái đáng kể, trong khi nhiều đề trong một trạng thái cổ phiếu quá trình cũng như bộ nhớ và các nguồn lực khác
  • quá trình có không gian địa chỉ riêng biệt, trong khi chủ đề chia sẻ không gian địa chỉ của họ
  • quá trình tương tác chỉ thông qua cơ chế giao tiếp liên quá trình hệ thống cung cấp.
  • Chuyển đổi bối cảnh giữa các luồng trong cùng một quy trình thường nhanh hơn so với chuyển đổi ngữ cảnh giữa các quy trình .
+1

về điểm số 2 ở trên: Đối với các chủ đề cũng CPU duy trì ngữ cảnh. – Jack

4

Chủ đề phần mọi thứ [1]. Có một không gian địa chỉ cho toàn bộ quá trình.

Mỗi luồng có ngăn xếp và sổ đăng ký riêng, nhưng tất cả ngăn xếp của chuỗi đều hiển thị trong không gian địa chỉ dùng chung.

Nếu một chuỗi phân bổ một số đối tượng trên ngăn xếp của nó và gửi địa chỉ đến một chuỗi khác, cả hai đều có quyền truy cập bình đẳng vào đối tượng đó.


Thực ra, tôi chỉ nhận thấy một vấn đề rộng lớn hơn: Tôi nghĩ bạn đang nhầm lẫn hai công dụng của từ phân khúc.

Định dạng tệp cho tệp thực thi (ví dụ: ELF) có phần riêng biệt, có thể được gọi là phân đoạn, chứa mã được biên dịch (văn bản), dữ liệu khởi tạo, biểu tượng liên kết, thông tin gỡ lỗi, v.v. phân đoạn heap hoặc stack ở đây, vì đó là các cấu trúc chỉ có thời gian chạy.

Các phân đoạn tệp nhị phân này có thể được ánh xạ vào không gian địa chỉ quy trình riêng biệt, với các quyền khác nhau (ví dụ, tệp thực thi chỉ đọc cho mã/văn bản và sao chép trên ghi không thể thực thi cho dữ liệu được khởi tạo).

Các vùng của không gian địa chỉ này được sử dụng cho các mục đích khác nhau, như phân bổ đống và ngăn xếp luồng, theo quy ước (được thực thi bởi thư viện thời gian chạy ngôn ngữ của bạn). Đó là tất cả chỉ là bộ nhớ mặc dù, và có lẽ không phân đoạn trừ khi bạn đang chạy trong chế độ ảo 8086. Mỗi ngăn xếp của luồng là một đoạn bộ nhớ được cấp phát tại thời điểm tạo luồng, với địa chỉ hàng đống hiện tại được lưu trữ trong thanh ghi ngăn xếp ngăn xếp và mỗi luồng giữ con trỏ ngăn xếp của chính nó cùng với các thanh ghi khác của nó.


[1] OK, tôi biết: mặt nạ tín hiệu, TSS/TSD vv không gian địa chỉ, bao gồm tất cả các phân đoạn chương trình lập bản đồ của mình, vẫn được chia sẻ mặc dù.

24

Cho người phỏng vấn biết rằng nó phụ thuộc hoàn toàn vào việc triển khai HĐH.

Lấy Windows x86 chẳng hạn. Chỉ có phân đoạn [1], Mã và Dữ liệu. Và cả hai đều được ánh xạ tới toàn bộ không gian địa chỉ 2GB (tuyến tính, người dùng). Base = 0, Limit = 2GB. Họ sẽ tạo ra một cái nhưng x86 không cho phép một phân đoạn là cả Đọc/Ghi và Thực thi. Vì vậy, họ đã thực hiện hai, và thiết lập CS để trỏ đến bộ mô tả mã, và phần còn lại (DS, ES, SS, vv) để trỏ đến [2] khác. Nhưng cả hai đều trỏ đến cùng một thứ!

Người phỏng vấn bạn đã đưa ra một giả định ẩn rằng họ không nói rõ, và đó là một mẹo ngu ngốc để kéo.

Vì vậy, liên quan đến

Q. Vì vậy, cho tôi biết là phân khúc chủ đề chia sẻ?

Các phân đoạn không liên quan đến câu hỏi này, ít nhất là trên Windows. Chủ đề chia sẻ toàn bộ không gian địa chỉ. Chỉ có 1 phân đoạn ngăn xếp, SS và nó trỏ đến cùng một thứ mà DS, ES và CS thực hiện [2]. I E. toàn bộ không gian người dùng đẫm máu. 0-2GB. Tất nhiên, điều đó không có nghĩa là chủ đề chỉ có 1 ngăn xếp. Đương nhiên, mỗi ngăn có ngăn xếp riêng, nhưng các phân đoạn x86 không được sử dụng cho mục đích này.

Có thể * nix làm điều gì đó khác biệt. Ai biết. Tiền đề câu hỏi dựa trên đã bị phá vỡ.


  1. Ít nhất cho không gian người dùng.
  2. Từ ntsd notepad: cs=001b ss=0023 ds=0023 es=0023
+0

Yep ... Phân đoạn phụ thuộc vào hệ điều hành và trình biên dịch/trình liên kết. Đôi khi có một phân đoạn BSS riêng biệt từ phân đoạn DATA. Đôi khi có RODATA (Dữ liệu như các chuỗi không đổi có thể ở các trang được đánh dấu là Chỉ đọc). Một số hệ thống thậm chí có thể chia DATA thành SMALL DATA (có thể truy cập từ cơ sở bù đắp 16 bit) và (FAR) DATA (yêu cầu bù đắp 32 bit để truy cập). Cũng có thể có thêm phân đoạn TLS DATA (Thread Local Store) được tạo trên cơ sở cho mỗi chủ đề – Adisak

+4

Ah, không! Bạn đang bối rối phân đoạn với các phần! Phần là cách trình liên kết chia mô-đun thành các phần (dữ liệu, rdata, văn bản, bss, v.v.) như bạn đã mô tả. Nhưng tôi đang nói về các phân đoạn, như được chỉ định trong phần cứng intel/amd x86. Không liên quan gì đến trình biên dịch/liên kết. Hy vọng có ý nghĩa. –

+0

Tuy nhiên, Adisak là đúng về cửa hàng Thread Local. Nó là riêng tư cho chủ đề và không được chia sẻ. Tôi biết hệ điều hành Windows và không chắc chắn về hệ điều hành khác. – Jack

2

Trong một khuôn khổ x86, người ta có thể phân chia như nhiều phân đoạn (lên đến 2^16-1). Các chỉ thị ASM SEGMENT/ENDS cho phép điều này, và các toán tử SEG và OFFSET cho phép khởi tạo các thanh ghi phân đoạn. CS: IP thường được khởi tạo bởi trình tải, nhưng đối với DS, ES, SS, ứng dụng chịu trách nhiệm khởi tạo. Nhiều môi trường cho phép cái gọi là "định nghĩa phân đoạn đơn giản" như .code, .data, .bss, .stack vv và, tùy thuộc vào "mô hình bộ nhớ" (nhỏ, lớn, nhỏ gọn, vv) trình tải khởi tạo phân đoạn đăng ký cho phù hợp. Thông thường .data, .bss, .stack và các phân đoạn thông thường khác (tôi đã không làm điều này từ 20 năm vì vậy tôi không nhớ tất cả) được nhóm lại trong một nhóm duy nhất - đó là lý do tại sao thường DS, ES và SS trỏ đến teh cùng một khu vực, nhưng đây chỉ là để đơn giản hóa mọi thứ.

Nói chung, tất cả thanh ghi phân khúc có thể có các giá trị khác nhau khi chạy theo thời gian. Vì vậy, câu hỏi phỏng vấn là đúng: một trong các MÃ, DỮ LIỆU, và STACK được chia sẻ giữa các chủ đề. Heap quản lý là cái gì khác - nó chỉ đơn giản là một chuỗi các cuộc gọi đến hệ điều hành. Nhưng nếu bạn không có một hệ điều hành nào, như trong một hệ thống nhúng - bạn vẫn có thể có/xóa mới trong mã của bạn?

Lời khuyên của tôi cho những người trẻ tuổi - đọc một số cuốn sách lập trình tốt. Có vẻ như chương trình giảng dạy đại học khá kém về khía cạnh này.

15

Nói chung, Chủ đề được gọi là quy trình trọng lượng nhẹ. Nếu chúng ta chia bộ nhớ thành ba phần thì nó sẽ là: Mã, dữ liệu và ngăn xếp. Mọi quá trình đều có mã, dữ liệu và các phần ngăn xếp riêng và do thời gian chuyển đổi ngữ cảnh này hơi cao một chút. Để giảm thời gian chuyển đổi ngữ cảnh, mọi người đã đưa ra khái niệm về luồng, chia sẻ Dữ liệu và phân đoạn mã với các luồng/quy trình khác và nó có phân đoạn STACK của riêng nó.

13

Quy trình có các phân đoạn mã, dữ liệu, đống và ngăn xếp. Bây giờ, con trỏ chỉ dẫn (IP) của một chủ đề hoặc chủ đề chỉ vào đoạn mã của quá trình. Các phân đoạn dữ liệu và heap được chia sẻ bởi tất cả các luồng. Bây giờ còn khu vực ngăn xếp thì sao? Điều gì thực sự là khu vực ngăn xếp? Một khu vực của nó được tạo ra bởi quá trình chỉ cho chủ đề của nó để sử dụng ... bởi vì ngăn xếp có thể được sử dụng một cách nhanh hơn nhiều so với đống vv Khu vực ngăn xếp của quá trình được chia giữa các chủ đề, tức là nếu có 3 chủ đề, sau đó vùng ngăn xếp của quá trình được chia thành 3 phần và mỗi phần được gán cho 3 luồng. Nói cách khác, khi chúng ta nói rằng mỗi luồng có ngăn xếp riêng của nó, ngăn xếp đó thực sự là một phần của vùng ngăn xếp quy trình được phân bổ cho mỗi luồng. Khi một luồng kết thúc việc thực hiện của nó, ngăn xếp của luồng được khai hoang bởi tiến trình. Trong thực tế, không chỉ ngăn xếp của một quá trình được chia giữa các chủ đề, nhưng tất cả các bộ thanh ghi mà một thread sử dụng như SP, PC và thanh ghi trạng thái là các thanh ghi của quá trình. Vì vậy, khi nói đến chia sẻ, mã, dữ liệu và vùng heap được chia sẻ, trong khi vùng ngăn xếp chỉ được phân chia giữa các luồng.

30

Điều gì đó thực sự cần phải được chỉ ra là có hai khía cạnh thực sự cho câu hỏi này - khía cạnh lý thuyết và khía cạnh triển khai.

Trước tiên, hãy xem xét khía cạnh lý thuyết. Bạn cần phải hiểu một quá trình là khái niệm để hiểu sự khác biệt giữa một quá trình và một sợi và những gì được chia sẻ giữa chúng.

Chúng tôi có sau từ phần 2.2.2 Các chủ đề cổ điển mẫu trong Modern Operating Systems 3e bởi Tanenbaum:

Mô hình quá trình được dựa trên hai khái niệm độc lập: tài nguyên nhóm và thực hiện. Đôi khi nó rất hữu ích để tách chúng; đây là nơi đề ra trong ....

Ông tiếp tục:

Một cách để nhìn vào một quá trình là nó là một cách để nhóm tài nguyên liên quan với nhau. Quá trình có một không gian địa chỉ chứa văn bản và dữ liệu chương trình, cũng như các tài nguyên khác. Các tài nguyên này có thể bao gồm các tệp đang mở, quy trình con, báo thức đang chờ xử lý, trình xử lý tín hiệu, thông tin kế toán và hơn thế nữa. Bằng cách đặt chúng với nhau dưới dạng một quy trình, chúng có thể được quản lý dễ dàng hơn. Khái niệm khác mà quy trình có là một chuỗi thực hiện, thường là được rút ngắn thành chỉ chuỗi. Chủ đề có bộ đếm chương trình giữ theo dõi trong đó lệnh thực hiện tiếp theo. Nó có các thanh ghi, trong đó giữ các biến làm việc hiện tại của nó. Nó có ngăn xếp chứa lịch sử thực thi , với một khung cho mỗi quy trình được gọi nhưng không phải là nhưng được trả lại từ. Mặc dù một luồng phải được thực hiện trong một số quy trình, luồng và quy trình của nó là các khái niệm khác nhau và có thể được xử lý riêng biệt . Các quá trình được sử dụng để nhóm các tài nguyên lại với nhau; các chủ đề là các thực thể được lập biểu để thực thi trên CPU.

Tiếp tục xuống ông cung cấp bảng sau:

Per process items    | Per thread items 
------------------------------|----------------- 
Address space     | Program counter 
Global variables    | Registers 
Open files     | Stack 
Child processes    | State 
Pending alarms    | 
Signals and signal handlers | 
Accounting information  | 

Trên đây là những gì bạn cần cho chủ đề để làm việc. Như những người khác đã chỉ ra, những thứ như phân đoạn là chi tiết triển khai phụ thuộc vào hệ điều hành.

+2

Đây là một lời giải thích tuyệt vời. Nhưng nó có lẽ nên được gắn lại với câu hỏi bằng cách nào đó để được coi là một "Trả lời" – catalyst294

Các vấn đề liên quan