2013-07-12 46 views
10

Đây có thể là câu hỏi không lập trình, tôi đã đọc về các đối tượng đồng bộ hóa chủ đề như sự kiện và cách nó được đặt làm trạng thái tín hiệu hoặc không được báo hiệu. Tuy nhiên tôi không thể hiểu những điều khoản này tín hiệu và không báo hiệu. Mỗi người đã thể hiện theo những cách khác nhau và tôi hơi bối rối.Trạng thái tín hiệu và không có tín hiệu

  1. This link khẳng định rằng

    Một hiệu trạng thái chỉ ra một nguồn lực có sẵn cho một quá trình hoặc thread để sử dụng nó. Trạng thái không báo hiệu cho biết tài nguyên đang được sử dụng.

  2. Tôi có một bài thuyết trình power point từ một trang web trường đại học trong đó nêu rằng

    Một đối tượng đó là trong tình trạng báo hiệu sẽ không gây ra một thread đang chờ đợi trên đối tượng để ngăn chặn và đối tượng mà không ở trạng thái được báo hiệu sẽ gây ra bất kỳ luồng nào chờ trên đối tượng đó để chặn cho đến khi đối tượng một lần nữa trở thành tín hiệu.

  3. bang này

    Một sự kiện ở trạng thái báo hiệu có nghĩa là nó có khả năng giải phóng các chủ đề chờ đợi sự kiện này để được báo hiệu. Một sự kiện ở trạng thái không được báo hiệu có nghĩa là nó sẽ không giải phóng bất kỳ luồng nào đang đợi sự kiện cụ thể này.

Một giải thích đơn giản về khái niệm này với ví dụ sẽ thực sự hữu ích.

Trả lời

14

Ok, 3 dấu ngoặc kép của bạn không tương thích. Nhưng chúng ta hãy đi một chút để thực hiện:

Mỗi đối tượng chờ đợi có giá trị boolean gắn liền với nó, được đặt tên là trạng thái báo hiệu, được sử dụng để chờ đối tượng đó; nếu đối tượng là báo hiệu, thì chức năng chờ sẽ không phải đợi; nếu đối tượng là không được báo hiệu, thì chức năng chờ sẽ chờ.

Bây giờ, điều này áp dụng như thế nào đối với một loại đối tượng cụ thể? Điều đó phụ thuộc vào bản chất đối tượng và đặc biệt là về ngữ nghĩa liên quan đến việc chờ đợi nó. Trên thực tế, trạng thái được báo hiệu được xác định theo điều kiện chờ. ví dụ (xem tài liệu để biết chi tiết):

  • Một mutex được báo hiệu khi nó không thuộc sở hữu.
  • Một quy trình/luồng được báo hiệu khi nó kết thúc.
  • Một semaphore được báo hiệu khi số của nó lớn hơn 0.
  • Bộ hẹn giờ chờ đợi được báo hiệu khi hết hạn.

Bạn có thể thích hơn nếu một mutex được báo hiệu khi sở hữu, nhưng thực ra đó là khi không được sở hữu. Đó là cần thiết để làm cho các chức năng chờ làm điều đúng.

Còn các sự kiện thì sao? Vâng, chúng là các đối tượng đơn giản, bạn có thể báo hiệu và hủy tín hiệu theo ý muốn, vì vậy trạng thái tín hiệu không có nghĩa bổ sung:

  • báo hiệu: Chủ đề sẽ không đợi.
  • không được báo hiệu: Chủ đề sẽ đợi.

Sự kiện cũng có điều này một chút đặc biệt (và IME thực tế không thể sử dụng đúng).

Bây giờ, chúng ta hãy nhìn vào dấu ngoặc kép của bạn:

Một hiệu trạng thái chỉ ra một nguồn lực có sẵn cho một quá trình hoặc thread để sử dụng nó. Trạng thái không báo hiệu cho biết tài nguyên đang được sử dụng.

Thực ra, đó là giải thích. Thông thường có một tài nguyên bạn đang cố gắng phân xử, và thường bạn chờ đợi nếu-và-chỉ-nếu tài nguyên đó đang được sử dụng, do đó, nó đang làm cho sự tương đương giữa tài nguyên-trong-sử dụng và chờ-cho-tài nguyên. Nhưng đó không phải là một yêu cầu kỹ thuật, chỉ là một trường hợp sử dụng thông thường.

Một đối tượng ở trạng thái được báo hiệu sẽ không gây ra chuỗi đang chờ đối tượng chặn và đối tượng không ở trạng thái được báo hiệu sẽ khiến bất kỳ chuỗi nào chờ đối tượng đó chặn cho đến khi đối tượng một lần nữa trở thành tín hiệu.

Đúng và cho điểm!

Sự kiện ở trạng thái được báo hiệu nghĩa là nó có khả năng giải phóng chuỗi đang chờ sự kiện này được báo hiệu. Một sự kiện ở trạng thái không được báo hiệu có nghĩa là nó sẽ không giải phóng bất kỳ luồng nào đang đợi sự kiện cụ thể này.

Tôi thấy từ ngữ này hơi khó hiểu ... nhưng nó không thêm gì khác so với từ trước.

+0

giải thích rất tốt mr rodrigo ngón tay cái lên. –

7

Vâng, trên thực tế tất cả các giải thích này là đồng dư.

Giải thích đơn giản nhất (và do đó không chính xác 100%) của một sự kiện là xem một sự kiện như một loại dịch vụ cờ được cung cấp bởi hệ điều hành. Một sự kiện được báo hiệu có thể được xem như là một cờ được đặt, một sự kiện chưa được đặt ở mặt khác có thể được xem như một cờ không được đặt.

Để triển khai sản xuất/tiêu dùng thread-hệ thống dựa trên lá cờ, bạn thường làm điều gì đó như sau (lưu ý vì lợi ích của sự đơn giản tôi bỏ bê cơ chế đồng bộ hơn nữa):

static volatile int flag = 0; 
static volatile char data = 'A'; 

// Some code to initialize the threads 

void producer() 
{ 
    while (1) 
    { 
     Sleep(1000); 
     data++; 
     flag = 1; 
    } 
} 

void consumer() 
{ 
    while (1) 
    { 
     /* Busy wait for the occurence of more data */ 
     while (!flag) 
     { 
      // wait for next data 
     } 

     flag = 0; 

     // process data 
    } 
} 

Thật không may điều này sẽ dẫn đến một sự lãng phí các chu kỳ xử lý trong vòng chờ đợi bận hoặc trì hoãn việc thực thi không mong muốn do một cuộc gọi Sleep được giới thiệu để giảm mức tiêu thụ CPU. Cả hai đều không mong muốn.

Để tránh các vấn đề như vậy với đồng bộ hóa tác vụ, hệ điều hành cung cấp các cơ chế cờ khác nhau (ví dụ: Sự kiện trong Windows). Với sự kiện, cài đặt và đặt lại cờ được thực hiện bởi hệ điều hành, hãy gọi SetEvent/ResetEvent. Để kiểm tra cờ, bạn có thể sử dụng WaitForSingleObject. Cuộc gọi này có sức mạnh để đặt một nhiệm vụ để ngủ cho đến khi sự kiện được báo hiệu là tối ưu về mức tiêu thụ CPU.

này biến ví dụ trên vào một cái gì đó như thế này:

static volatile char data = 'A'; 
static HANDLE newDataEvent = INVALID_HANDLE_VALUE; 

// Some code to initialize the threads and the newDataEvent handle 

void producer() 
{ 
    while (1) 
    { 
     Sleep(1000); 
     data++; 
     SetEvent(newDataEvent); 
    } 
} 

void consumer() 
{ 
    while (1) 
    { 
     if (WaitForSingleObject(newDataEvent, INFINITE) == WAIT_OBJECT_0) 
     { 
      ResetEvent(newDataEvent); 
      // process data 
     } 
    } 
} 
+0

giải thích rất tốt –

9

Cách dễ dàng để nghĩ về nó: "hiệu" = "bật đèn xanh"

Green Light Nếu bạn đang lái xe và bạn nhìn thấy một ánh sáng màu xanh lá cây bạn không dừng lại (đây là chủ đề xem xét một sự kiện, tìm thấy nó là báo hiệu và tiếp tục mà không bị chặn).

enter image description here Nếu bạn nhìn thấy đèn đỏ bạn dừng lại và chờ nó trở thành màu xanh lá cây và sau đó tiếp tục (an toàn trong kiến ​​thức các chủ đề khác tất cả hiện không được báo hiệu, do đó đang chờ hoặc sẽ đợi ... ánh sáng đỏ!)

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