Là chủ đề sao chép khi gọi ngã ba?


31

Nếu tôi có một chương trình đang chạy với các luồng và gọi fork()trên một hệ thống dựa trên unix, các luồng có được sao chép không? Tôi biết rằng bộ nhớ ảo cho quy trình hiện tại được sao chép 1: 1 sang quy trình mới được sinh ra. Tôi biết rằng các luồng có ngăn xếp riêng của chúng trong bộ nhớ ảo của một quá trình. Vì vậy, ít nhất là chồng các chủ đề cũng nên được sao chép. Tuy nhiên, tôi không biết liệu có thêm bất kỳ chủ đề nào không nằm trong bộ nhớ ảo hay không và do đó KHÔNG được sao chép. Nếu không có, hai quá trình chia sẻ các chủ đề hay chúng là bản sao độc lập?

Câu trả lời:


29

Không.

Chủ đề không được sao chép trên fork(). Đặc tả POSIX cho biết (nhấn mạnh là của tôi):

ngã ba - tạo ra một quy trình mới

Một quy trình sẽ được tạo ra với một chủ đề duy nhất . Nếu một quy trình đa luồng gọi fork (), quy trình mới sẽ chứa một bản sao của luồng gọi và toàn bộ không gian địa chỉ của nó, có thể bao gồm các trạng thái của mutexes và các tài nguyên khác. Do đó, để tránh lỗi, tiến trình con chỉ có thể thực hiện các hoạt động an toàn tín hiệu async cho đến khi một trong các hàm exec được gọi.

Để khắc phục vấn đề này, tồn tại một pthread_atfork()chức năng để giúp đỡ.


7

người đàn ông ngã ba :

Quá trình con được tạo ra với một luồng duy nhất, một luồng được gọi là fork (). Toàn bộ không gian địa chỉ ảo của cha mẹ được sao chép ở trẻ, bao gồm các trạng thái của mutexes, biến điều kiện và các đối tượng pthreads khác; việc sử dụng pthread_atfork (3) có thể hữu ích để xử lý các vấn đề mà điều này có thể gây ra.


Nhưng điều đó có vẻ kỳ lạ: Tại sao ngăn xếp cho các luồng trong quá trình gọi fork sẽ được sao chép nếu các luồng thực tế (mà tôi không biết có chứa bộ nhớ ở nơi nào khác ngoài bộ nhớ ảo) thì không?

Vâng, tại sao nó là một câu hỏi khác nhau hoàn toàn. Tôi không biết các quyết định thiết kế ban đầu dẫn đến việc thực hiện đó. Nếu bạn quan tâm, bạn nên hỏi nó như một câu hỏi riêng biệt.
kaylum

@dip nhưng chồng các chủ đề khác không được sao chép, ai nói vậy?
Jean-Baptiste Yunès

1
@ Jean-BaptisteYunès Trong các hệ thống unix, có một cấu trúc đại diện cho bộ nhớ ảo cho một quá trình. Đó là một bản sao. Không chỉ heap và bss

6
bạn có được toàn bộ không gian bộ nhớ - và do đó, ngăn xếp của tất cả các luồng. bạn cần điều đó bởi vì không có giới hạn về nơi con trỏ sống trong ngăn xếp (hoặc bộ nhớ tĩnh) có thể truy cập vào luồng còn lại đang trỏ - chúng rất có thể được trỏ đến dữ liệu sống trong ngăn xếp của một số luồng trong quy trình ban đầu
davidbak

4

Từ Thông số kỹ thuật cơ sở nhóm mở số 7, phiên bản ngã ba 2018 :

Một quy trình sẽ được tạo ra với một chủ đề duy nhất. Nếu một quy trình đa luồng gọi fork () , quy trình mới sẽ chứa một bản sao của luồng gọi và toàn bộ không gian địa chỉ của nó, có thể bao gồm các trạng thái của mutexes và các tài nguyên khác. Do đó, để tránh lỗi, tiến trình con chỉ có thể thực hiện các hoạt động an toàn tín hiệu async cho đến khi một trong các hàm exec được gọi.

Khi ứng dụng gọi fork () từ trình xử lý tín hiệu và bất kỳ trình xử lý ngã ba nào được đăng ký bởi pthread_atfork () sẽ gọi một hàm không an toàn tín hiệu, hành vi không được xác định.


-2

Ban đầu, "fork" đã đạt được bằng cách ghi tác vụ vào đĩa và sau đó, thay vì đọc trong một luồng khác (sẽ được thực hiện nếu hoán đổi tác vụ với một cái khác), sửa đổi ID nhiệm vụ của hình ảnh vẫn còn trong bộ nhớ và tiếp tục với việc thực hiện của nó (như nhiệm vụ mới). Đây là một sửa đổi rất đơn giản cho cơ chế chuyển đổi tác vụ cơ bản, trong đó chỉ có một tác vụ sẽ chiếm bộ nhớ RAM tại một thời điểm.

Tất nhiên, khi quản lý bộ nhớ phức tạp hơn, sơ đồ này đã được sửa đổi cho phù hợp với môi trường mới.


Tò mò tại sao điều này đã được bỏ phiếu. Đây là cách mà Unix đã làm.
Licks nóng

Đây là cái nhìn sâu sắc thú vị, nhưng nó đề cập đến chủ đề ở đâu? Không giống như một câu trả lời cho tôi.
lãng phí
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.