2008-10-30 40 views
5

Tôi có một giao diện HW đơn mà tôi muốn sử dụng từ hai ứng dụng (quy trình) trên cùng một máy trạm. HW yêu cầu một cuộc gọi khởi tạo duy nhất sau đó một trong hai ứng dụng sử dụng chức năng tương tự (trong cùng một thư viện) để thực hiện nhiều giao dịch với HW.Làm cách nào để đồng bộ hóa hai quy trình?

Vì vậy, mỗi ứng dụng nên hành động như thế này:

main() 
    // I don't know if another app already init'ed the HW 
    ret = hw_init_lock(non-blocking) 

    if ret = OK 
     // no one else has done this, I have to 
     init_hw() 
    else 
     //someone else has already init'ed the HW, I gotta make sure it stays that way 
     //as long as I'm alive 
     increment_hw_init_ref_counter() 

    hw_trans_lock(blocking) 
    hw_trans() 
    hw_trans_unlock() 
    .... 

    //exit app, uninit hw if we are last out 
    ret = decrement_hw_init_ref_counter() 
    if ret == 0 
     uninit_hw() 

    exit(0) 

cơ chế tôi có thể sử dụng trong các khóa và tài liệu tham khảo cuộc gọi đếm được chia sẻ giữa hai ứng dụng là gì? Tôi đang nghĩ tên là ống mkfifo().

Trả lời

2

Vì bạn chỉ cần một số đếm semaphore của một, một mutex đủ.

+4

Cột POSIX có thể được chia sẻ giữa các quá trình liên quan, trong khi mutexes pthread không thể. – ephemient

9

POSIX semaphore là cách để thực hiện. Vì bạn muốn chia sẻ cùng một semaphore qua các quy trình, bạn cần phải sử dụng semaphore có tên:

Một semaphore được đặt tên được xác định bởi tên tên/somename. Hai quy trình có thể hoạt động trên cùng một semaphore được đặt tên bằng cách chuyển cùng một tên cho sem_open (3).

1

tôi cho rằng

... được chia sẻ giữa hai ứng dụng?

có nghĩa là bạn muốn hai thứ này hoạt động dưới dạng các quy trình riêng biệt? Nếu điều đó không đúng, và chúng đang chạy như một quá trình đơn lẻ (với nhiều luồng), thì các đề xuất về các ẩn dụ và các mutex là lựa chọn tốt nhất và nên khá đơn giản.

Lưu ý rằng câu trả lời sẽ phụ thuộc vào chính xác cách bạn truy cập phần cứng này. Ví dụ, nếu nó được hiển thị thông qua một tệp thì có thể sử dụng khóa tệp thông thường.

Tuy nhiên, nếu bạn đang cố đồng bộ hóa quyền truy cập vào phần cứng qua hai quy trình thì đó là vấn đề khác. Tôi đoán điều đầu tiên cần nói là nó sẽ dễ dàng hơn để đồng bộ hóa, nếu bạn có thể, để có một quy trình duy nhất chịu trách nhiệm truy cập phần cứng. Trong mô hình này, bạn có thể có một quá trình hoạt động như một máy chủ cho phần cứng - chấp nhận các yêu cầu từ các quy trình khác và thực hiện các lần đọc và viết thay cho họ. Chỉ cần về bất kỳ hình thức liên lạc liên bộ nào sẽ phù hợp, nhưng đơn giản như hàng đợi thông báo (link) có thể phù hợp với một số cấu trúc dữ liệu thích hợp (ví dụ: cờ để cho biết đó là hoạt động đọc hoặc ghi). của phần cứng, số byte, bộ đệm (trong trường hợp viết))

Nếu đặt tất cả phần cứng trực tiếp vào một quy trình không phù hợp thì bạn sẽ phải sử dụng lược đồ đồng bộ thích hợp. Tôi sẽ điều tra việc sử dụng khóa tệp (và triển khai sơ đồ mutex thô sơ) hoặc sử dụng các ẩn dụ có tên (như albertb đã đề xuất)

4

Biến thể và biến Mutex/điều kiện là các nguyên tố tốt, hiệu suất rất cao phù hợp để sử dụng ở giữa các luồng hoặc giữa các quy trình.

Tất cả những điều này đều dựa trên ý tưởng (và thường là trên thực tế) của thử nghiệm và thiết lập hoặc các hoạt động nguyên tử khác được thực hiện trên bộ nhớ dùng chung.

Nếu bạn muốn phân phối các quy trình của mình qua mạng, thì các ẩn dụ và các mutex có thể không phù hợp với bạn - chúng chỉ hoạt động trên một máy. Ống và ổ cắm thường có khả năng mở rộng mạng hơn.

Một bản tóm tắt ngắn gọn về mutexes, các biến điều kiện và Cột:

Mutexes

Một mutex là một nguyên thủy có thể được hoặc bị khóa, hoặc mở khóa. Quá trình/chủ đề mà khóa nó phải là một trong những để mở khóa nó. Điều này quyền sở hữu khía cạnh cho phép hệ điều hành áp dụng một số tối ưu hóa thú vị, chẳng hạn như ưu tiên thừa kế và ưu tiên giao thức trần (để tránh ưu tiên đảo ngược). tuy nhiên, mutex không có số được liên kết với nó. Bạn không thể khóa một mutex đã bị khóa, nói chung, và giữ lại bộ nhớ rằng nó đã được "khóa hai lần" (có một số phần mở rộng cho phép điều này, tôi nghĩ, nhưng chúng không có ở mọi nơi)

Biến điều kiện

Một mutex tuyệt vời cho ... tốt, loại trừ MUTual. Nhưng nếu bạn cần chặn một điều kiện liên quan đến đối tượng mà bạn có loại trừ lẫn nhau thì sao? Đối với điều này, bạn sử dụng biến điều kiện hoặc CV. CV được liên kết với một mutex. Ví dụ: giả sử tôi có hàng đợi dữ liệu đầu vào mà các quy trình của tôi muốn truy cập. Một lấy mutex để nó có thể nhìn vào hàng đợi mà không sợ nhiễu. Tuy nhiên, nó tìm thấy hàng đợi trống và muốn chờ đợi một cái gì đó để đi vào hàng đợi. Do đó, nó chờ trên biến điều kiện "hàng đợi không trống". Phần thú vị ở đây là, bởi vì CV được kết hợp với mutex, mutex được tự động mua lại sau khi biến điều kiện được báo hiệu. Vì vậy, một khi quá trình tỉnh dậy sau khi chờ đợi trên CV, nó biết rằng nó có quyền truy cập độc quyền một lần nữa vào hàng đợi. Những gì nó làm không biết là hàng đợi thực sự có bất kỳ thứ gì trên đó - có lẽ hai quá trình chờ đợi trên CV - một thứ xuất hiện - và ưu tiên đầu tiên là "điều" trước khi điều thứ hai đánh thức lên. Vì vậy, bất cứ khi nào bạn sử dụng một CV, bạn cần phải kiểm tra lại tình trạng này, như thế này:

mutex_enter(m); 
while (! condition) { 
    cond_wait(m, c); // drop mutex lock; wait on cv; reacquire mutex 
} 
//processing related to condition 
mutex_exit(m); 

Semaphores

OK, đó là mutexes và các biến điều kiện. Semaphores đơn giản hơn. Chúng có thể được tăng lên và giảm đi bởi bất kỳ quá trình nào. Họ có trí nhớ - họ đếm - vì vậy bạn có thể sử dụng chúng để xác định có bao nhiêu tình trạng đã xảy ra. Không phải như vậy với các biến condiiton. Ngoài ra, bởi vì các semaphores có thể được giảm đi bởi một tiến trình và tăng lên bởi một tiến trình khác, chúng không có khía cạnh quyền sở hữu - vì vậy không có sự thừa kế ưu tiên, không thể tránh được ưu tiên đảo ngược ưu tiên.

Bây giờ, cuối cùng - tất cả các cơ chế này đều yêu cầu bộ nhớ dùng chung để thực hiện hiệu quả. Điều này có thể tốt cho bạn, nhưng hãy lưu ý - nếu bạn tin rằng ứng dụng của bạn cuối cùng có thể được phân phối, thì mutexes, biến điều kiện và semaphores có thể không dành cho bạn. Ống và ổ cắm, trong khi chi phí cao hơn nhiều, có khả năng được mở rộng qua mạng khá đơn giản.

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