2009-05-23 42 views
5

Ai đó có thể giải thích đồng bộ hóa điều kiện cho tôi không?Đồng bộ hóa điều kiện là gì?

Một ví dụ (tốt nhất là trong C#) cũng sẽ được đánh giá cao.

+1

Tôi đã nghe về "đồng bộ hóa": thường là cụm từ liên quan đến đa luồng, cụ thể với các loại "khóa" khác nhau có thể được yêu cầu để 'đồng bộ hóa' các chuỗi để làm cho mã "an toàn chỉ ". Nhưng tôi không biết, cụ thể, "* điều kiện * đồng bộ hóa". – ChrisW

Trả lời

8

Có vẻ như giáo sư của bạn đang nói về luồng. Luồng cho phép các chương trình máy tính làm nhiều thứ cùng một lúc. Các hành động bắt đầu một chủ đề mới trong khi một đang chạy được gọi là "quay lên một sợi" bởi các lập trình viên máy tính.

Chủ đề có thể chia sẻ cùng một không gian bộ nhớ. Đồng bộ hóa điều kiện (hoặc đơn thuần là đồng bộ hóa) là bất kỳ cơ chế nào bảo vệ các vùng của bộ nhớ khỏi bị sửa đổi bởi hai luồng khác nhau cùng một lúc.

Giả sử bạn đang đi mua sắm và vợ ở nhà thanh toán hóa đơn. Đây là một ví dụ ngây thơ, và nó không thực sự hoạt động theo cách này trong cuộc sống thực, nhưng nó sẽ là một minh họa đơn giản.

Vợ của bạn đang thanh toán hóa đơn trực tuyến. Đồng thời, bạn đang vuốt thẻ tín dụng của bạn tại cửa hàng tạp hóa. Cả hai hành động liên quan đến việc chuyển tiền ra khỏi tài khoản séc của bạn. Để mô phỏng hoạt động này, chúng ta viết đoạn mã sau:

public class MyBanking 
{ 
    static double myAccountBalance; 
    // 
    public void DebitAccount(double debitAmount) 
    { 
     Console.Writeline("Your Old Balance is: " + myAccountBalance.ToString()); 
     Console.Writeline("Your Debit is:  " + debitAmount.ToString()); 
     myAccountBalance = myAccountBalance - amount; 
     Console.Writeline("Your New Balance is: " + myAccountBalance.ToString()); 
    } 
} 

giả thuyết, vợ của bạn đang chạy một ví dụ ("bản sao") của lớp này trên một thread, bạn đang chạy một thể hiện trên thread khác. Biến myAccountBalance được khai báo tĩnh để cho phép nó được chia sẻ giữa cả hai cá thể đang chạy (bạn và vợ bạn chỉ có một tài khoản kiểm tra).

Bạn làm cho ghi nợ của bạn bằng cách gọi mã như thế này:

MyBanking bankingObject = new MyBanking(); 
bankingObject.DebitAccount(100); 

vợ của bạn làm cho ghi nợ của mình cùng một lúc:

MyBanking bankingObject = new MyBanking(); 
bankingObject.DebitAccount(50); 

gì xảy ra nếu chủ đề của bạn bị gián đoạn bởi chủ đề của vợ bạn sau khi số dư cũ của bạn được in trên màn hình, nhưng trước khi số dư mới được in? Chủ đề của vợ bạn ghi nợ tài khoản và trả lại quyền kiểm soát cho chủ đề của bạn.Vợ của bạn xem đây trên màn hình:

Your Old Balance is: 2000 
Your Debit is:  50 
Your New Balance Is: 1950 

Khi máy tính in ra cân bằng mới trên màn hình của bạn, nó sẽ là sai lầm, bởi vì thẻ ghi nợ của vợ bạn sẽ được tính cũng có. Bạn sẽ thấy một cái gì đó như thế này:

Your Old Balance is: 2000 
Your Debit is:  100 
Your New Balance Is: 1850 

Để khắc phục điều này, chúng tôi bao quanh mã phương thức của chúng tôi bằng một tuyên bố khóa. Tuyên bố khóa khiến tất cả các chủ đề khác phải chờ cho ví dụ của chúng tôi kết thúc. Các mã mới trông như thế này: chủ đề

public class MyBanking 
{ 
    static double myAccountBalance; 
    // 
    public void DebitAccount(double debitAmount) 
    { 
     lock (this) 
     { 
      Console.Writeline("Your Old Balance is: " + myAccountBalance.ToString()); 
      Console.Writeline("Your Debit is:  " + debitAmount.ToString()); 
      myAccountBalance = myAccountBalance - amount; 
      Console.Writeline("Your New Balance is: " + myAccountBalance.ToString()); 
     } 
    } 
} 

của vợ bạn bây giờ sẽ chờ đợi cho mã của bạn trong báo cáo kết quả khóa để kết thúc thực hiện, trước khi mã của vợ bạn bắt đầu thực hiện. Số dư mới của bạn bây giờ sẽ chính xác, bởi vì không còn khả năng chủ đề của vợ bạn thay đổi số dư trong khi bạn hoàn thành giao dịch CỦA BẠN. Trên màn hình của bạn, bây giờ bạn sẽ thấy điều này:

Your Old Balance is: 2000 
Your Debit is:  100 
Your New Balance Is: 1900 

vợ bạn sẽ thấy điều này:

Your Old Balance is: 1900 
Your Debit is:  50 
Your New Balance Is: 1850 

Đây là đồng bộ hóa.

+0

Còn có một thứ gọi là biến điều kiện. Xem bài viết này để biết chi tiết: http://en.wikipedia.org/wiki/Monitor_%28synchronization%29 –

+0

Vợ có đầu ra sai. 1900 - 50! = 1800 –

+0

@IgorGorjanc: Cảm ơn. –

2

Về cơ bản nó là một mẫu thiết kế cho chủ đề cần

a) đồng bộ hóa quyền truy cập vào một nguồn tài nguyên

b) đôi khi chờ đề khác cho đến khi một điều kiện nhất định được đáp ứng

Bạn hỏi này trong một C# bối cảnh, NET cung cấp hỗ trợ cho điều này với Monitor.Wait và Monitor.Pulse (và với hàm bao quanh các đối tượng Win32 khác nhau như WaitEventhandle).

Đây là số đẹp queue example trên SO.

Các chi tiết kỹ thuật chính như sau:

lock(buffer) // is Monitor.Enter(buffer) ... finally Monitor.Leave(buffer) 
{ 
    while (buffer.Count < 1) 
    { 
     Monitor.Wait(buffer); 
    } 
    ... 
} 

Thông báo như thế nào có một Chờ-khi-nhốt trong đó. Nó trông giống như một bế tắc nhưng Wait sẽ nhả khóa trong khi nó đang chờ. Mã bên trong lock() { } vẫn có quyền truy cập độc quyền vào bộ đệm khi nó chạy.

Và sau đó thread khác có để báo hiệu khi nó đặt cái gì đó vào bộ đệm:

Monitor.Pulse(buffer); 
1

Mã ở trên gần như chính xác nhưng thực sự là sai. Bằng cách sử dụng lock(this), bạn sẽ chỉ khóa thể hiện của mình trong lớp MyBanking, nhưng vợ của bạn sẽ khóa cô ấy. Để khóa quyền truy cập vào biến được chia sẻ, bạn có thể khóa loại (tức là lock(typeof(MyBanking))) hoặc bạn có thể giới thiệu một biến được chia sẻ mới và khóa khóa đó (bạn không thể khóa một int để mọi người thường tạo một đối tượng như sau.

class MyBanking 
{ 
    static object lockObj = new object(); 
    static double myAccountBalance; 
    public void DebitAccount(double debitAmount) 
    { 
     lock (lockObj) 
1

đồng bộ đã được giải thích rõ ràng rồi. Tuy nhiên, tình trạng đồng bộ hóa đặc biệt dictates rằng một quá trình/thread thực thi chỉ sau khi một số điều kiện được đáp ứng. Thông thường, tình trạng này sẽ là một số quá trình khác/thread đã thực hiện.

Trong ví dụ về việc ghi nợ một tài khoản và xem số dư. Nếu việc xem số dư của bạn là một phương thức được đồng bộ hóa riêng và chúng tôi chỉ muốn xem số dư sau khi tài khoản của bạn bị ghi nợ, thì điều này sẽ yêu cầu đồng bộ hóa điều kiện.

Đồng bộ hóa điều kiện được mô tả rất rõ bởi producer-consumer problem.

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