Khi bạn bắt đầu nhiều luồng trên bộ xử lý đa lõi, chúng có được đảm bảo xử lý bởi các lõi khác nhau không?


24

Tôi có bộ xử lý Pentium core i5, có 4 lõi. Nếu tôi làm điều này trong một chương trình điều khiển C #

var t1 = new Thread(Thread1);
var t2 = new Thread(Thread2);
t1.Start();
t2.Start();

các chủ đề t1 và t2 có được đảm bảo để chạy trên các lõi riêng biệt không?


1
Giả sử thời gian chạy C # sử dụng các lệnh gọi hệ thống gốc tương đương để sinh ra một luồng khác (và do đó thực sự song song; đây không phải là trường hợp của mọi thứ, như Khóa phiên dịch toàn cầu khét tiếng của CPython ), điều này sẽ chỉ phụ thuộc vào trình lập lịch trình / tác vụ của hệ điều hành . Tuy nhiên, nói chung, mã thực sự là luồng an toàn nếu bạn giả sử điều đó t1t2được thực thi tại các thời điểm khác nhau theo thứ tự tùy ý (ví dụ: có thể t2bắt đầu trước t1 trong một số mô hình).
Đột phá

2
Tôi không biết rằng có bộ xử lý Pentium i5. Có lẽ bạn có nghĩa là Core i5? Kén chọn, khó tính. Tôi biết: D
JosephGarrone

Câu trả lời:


18

Bạn không thể đảm bảo trong .Net rằng hai Threads chạy trên hai lõi riêng biệt. Trên thực tế, bạn cũng không thể đảm bảo rằng một cái Threadsẽ chỉ chạy trên một lõi (!) .

Điều này là do các luồng được quản lý không giống như các luồng của HĐH - một luồng được quản lý duy nhất có thể sử dụng nhiều luồng của HĐH để hỗ trợ nó. Trong C #, bạn chỉ từng giao dịch trực tiếp với Threadcác s được quản lý (ít nhất, mà không dùng đến p / invoke để gọi các hàm phân luồng WinAPI, điều mà bạn không bao giờ nên làm) .

Tuy nhiên, bộ lập lịch luồng .Net và Windows rất tốt trong những gì họ làm - họ sẽ không chạy hai luồng trên một lõi trong khi lõi thứ hai hoàn toàn không hoạt động. Vì vậy, nói chung, bạn không cần phải lo lắng về nó.


Trong thực tế, .Net Threads là các luồng hệ điều hành. Nhưng đó không phải là lý do tại sao không có gì đảm bảo rằng một luồng sẽ luôn luôn thực thi trên cùng một lõi.
Svick

2
@svick: Trong thực tế, trên x86 , điều đó là đúng. Tuy nhiên, tiêu chuẩn tuyên bố rõ ràng rằng bạn không thể dựa vào hành vi này, vì vậy nó có thể thay đổi trong tương lai. Trên thực tế, điều đó không đúng trên các phiên bản khác của .Net CLR, như của XBox 360.
BlueRaja - Daniel Pflughoeft

@BlueRaja - Câu hỏi cụ thể về phiên bản CLR mà chúng ta đang nói đến. Bạn có thể đảm bảo một cái gì đó sẽ tồn tại trên hai lõi riêng biệt bằng cách sử dụng các luồng không đồng bộ bởi vì điều đó có nghĩa là chúng sẽ xảy ra không đồng bộ với nhau. Mã ví dụ hiện tại là một cuộc gọi đồng bộ về mặt kỹ thuật. Tất nhiên hệ điều hành quyết định lõi nào sẽ được sử dụng.
Ramhound

@Ramhound "Bạn có thể đảm bảo một cái gì đó sẽ tồn tại trên hai lõi riêng biệt bằng cách sử dụng các luồng không đồng bộ" - đó là sai. Các asynctừ khóa (đó là những gì tôi giả sử bạn đang nói đến, là "chủ đề async" là không cần thiết) là đường chỉ cú pháp cho việc sử dụng một BackgroundWorkersợi, mà là giống như bất kỳ chủ đề Net khác - bạn có thể không đảm bảo cho dù đó sẽ chạy trên một lõi riêng hay không.
BlueRaja - Daniel Pflughoeft

@BlueRaja - Nếu hai luồng không đồng bộ được bắt đầu, cả hai sẽ chạy cùng lúc với điều kiện có 2 lõi CPU. Nếu chỉ có một thì hệ điều hành sẽ lên lịch khi mỗi luồng sẽ được ưu tiên và chạy và tình huống đập luồng đơn điển hình của bạn sẽ xảy ra. Đây là cách tôi được dạy cách CPU xử lý đa luồng.
Ramhound

15

Không, HĐH và CPU sẽ quyết định chạy gì và khi nào. trong ví dụ đơn giản mà bạn đã chỉ ra, để loại trừ các tác vụ khác, có, những nhiệm vụ đó rất có thể sẽ chạy song song trên các lõi riêng biệt, nhưng hiếm khi có một đảm bảo rằng đó sẽ là trường hợp.

Bạn có thể sử dụng mối quan hệ luồng để cố gắng kiểm soát việc phân bổ lõi cho một luồng nhất định.

Ngoài ra, hãy xem xét các ưu tiên lập lịch để sắp xếp bộ bài theo các chủ đề nên hoàn toàn song song và có thể chờ.


1
Tôi cũng muốn thêm rằng, với các công nghệ ảo hóa, có một lớp khác giữa chương trình của bạn và phần cứng. Những gì HĐH trình bày cho ứng dụng có thể không chính xác về mặt vật lý.
Keltari

1
Đó là các hàm WinAPI cho các luồng hệ điều hành, không phải cho các luồng được quản lý. Chúng không bao giờ được gọi từ C #, vì chúng có thể can thiệp nghiêm trọng vào bộ lập lịch luồng .Net.
BlueRaja - Daniel Pflughoeft
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.