2011-01-21 47 views
6

Tôi đang đọc "Trình điều khiển thiết bị Linux phiên bản thứ ba", chương về tính đồng nhất và điều kiện chủng tộc. Có một ví dụ tôi không hoàn toàn hiểu; họ đang nói về một mô hình phổ biến trong lập trình hạt nhân, khi cần bắt đầu hoạt động (fo rexample, chuỗi hạt nhân mới hoặc quy trình người dùng, yêu cầu quá trình hiện tại hoặc hành động dựa trên phần cứng) bên ngoài luồng hiện tại, hãy đợi hoạt động đó hoàn thành. Ví dụ về giải pháp không hiệu quả là:Linux mutexes hạt nhân

struct semaphore sem; 
init_MUTEX_LOCKED(&sem); 
start_external_task(&sem); 
down(&sem); 

Sau đó, chúng đề xuất nhiệm vụ bên ngoài để gọi (& sem) khi hoàn thành công việc.

Tôi không hiểu lý do tại sao chúng ta không thể làm điều đó theo cách này:

struct semaphore sem; 
down(&sem); 
start_external_task(&sem); 

Tại sao là cần thiết để tạo mutex trong trạng thái bị khóa và sau đó được các mutex sau khi nhiệm vụ đã được bắt đầu?

Mong muốn được nghe từ bạn! Cảm ơn.

Trả lời

10

Khi bạn gọi xuống(), chuỗi của bạn sẽ chặn cho đến khi một chuỗi khác báo hiệu semaphore. Kể từ khi thread khác chưa được bắt đầu, thread sẽ chặn vô thời hạn. Đó là lý do tại sao bạn cần phải bắt đầu chủ đề đầu tiên, và sau đó gọi xuống() để chặn cho đến khi chủ đề kết thúc.

Nếu chuỗi kết thúc trước khi bạn gọi xuống(), điều đó là ổn, vì semaphore sẽ được báo hiệu và xuống() sẽ chỉ xóa tín hiệu và trả lại.

+6

+1, nhưng tôi nghĩ sẽ tốt hơn nếu sử dụng thuật ngữ 'semaphore' thay vì' mutex'. SEMAPHORE: có thể lên/xuống bởi bất kỳ chủ đề nào. MUTEX: có quyền sở hữu, chỉ khóa chủ sở hữu có thể tạo mutex. Trong trường hợp này chúng ta cần sử dụng semaphore, vì mục đích của nó là giao tiếp giữa các chủ đề ... – Vojta

+0

@Vojita: Tôi đồng ý. Tôi đã sử dụng thuật ngữ mutex vì câu hỏi đề cập đến semaphore là một mutex. –

3

Trong ví dụ đầu tiên xuống (& sem) sẽ đợi external_task gọi lên (& sem) và tạm dừng có hiệu quả chủ đề chính cho đến khi hoàn thành nhiệm vụ. Trong mã của bạn xuống() sẽ khóa chủ đề chính mãi mãi vì không có nhiệm vụ chưa gọi lên()

1

Cuộc gọi:

init_MUTEX_LOCKED(&sem); 

Tạo một semaphore mới trong "chế độ mutex" khởi tạo vào 0. Điều này có nghĩa là cuộc gọi tới down() sẽ chặn. Một cuộc gọi tương ứng:

init_MUTEX(&sem); 

có tạo ra một semaphore khởi tạo 1.

Trong ví dụ đầu tiên bạn khởi semaphore để 0, bạn tạo external_task của bạn và bạn gọi down() chặn cho đến khi nhiệm vụ của bạn gọi up().

Trong ví dụ thứ hai bạn không khởi tạo semaphore, hãy gọi down() thực thi chặn và không có hoạt động bên ngoài nào có thể gọi up() để bỏ chặn bạn. Các cuộc gọi để tạo external_task do đó không bao giờ đạt được.

Ngẫu nhiên, quá trình khởi tạo semaphore với init_MUTEX_LOCKED đã bị xóa trong phiên bản hạt nhân 2.6.37.

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