2012-12-03 24 views
18

Từ những gì tôi hiểu, bạn viết Linux Daemon của bạn lắng nghe yêu cầu trong một vòng lặp vô tận.
Cái gì đó như ..Vòng lặp while vô tận có chiếm tài nguyên CPU không?

int main() { 
    while(1) { 
     //do something... 
    } 
} 

ref: http://www.thegeekstuff.com/2012/02/c-daemon-process/

Tôi đọc mà ngủ một chương trình làm cho nó đi vào chế độ chờ để nó không ăn lên tài nguyên.

1.Nếu tôi muốn daemon của mình kiểm tra yêu cầu sau mỗi 1 giây, liệu sau đây có phải là tài nguyên tiêu thụ không?

int main() { 
    while(1) { 
     if (request) { 
      //do something... 
     } 
     sleep(1) 
    } 
} 

2.Nếu tôi muốn xóa chế độ ngủ, điều đó có nghĩa là mức tiêu thụ CPU sẽ tăng 100%?

3. Có thể chạy vòng lặp vô tận mà không cần ăn tài nguyên không? Nói .. nếu nó không làm gì ngoài việc chỉ lặp lại chính nó. Hoặc chỉ ngủ (1).

Vòng lặp vô tận và tài nguyên CPU là điều bí ẩn đối với tôi.

+1

Ngủ báo cho trình lập lịch biểu thực hiện một số quy trình khác chạy trên CPU thay vì quy trình của bạn trong một khoảng thời gian cụ thể (quá đơn giản). Chương trình của bạn sẽ không tiêu tốn bất kỳ tài nguyên CPU nào khi đang ngủ. Ngay cả khi ngủ chỉ trong vài mili giây làm cho mọi thứ trôi chảy trong một vòng lặp vô tận như bạn đã thể hiện nó. –

+3

Nếu bạn đang * nghe * thì bạn nên sử dụng một số syscall ghép kênh như 'poll (2)' (hoặc cũ hơn, gần như lỗi thời, 'select (2)') –

Trả lời

12

Có thể chạy vòng lặp vô tận mà không cần ăn tài nguyên không? Nói .. nếu nó không làm gì ngoài việc chỉ lặp lại chính nó. Hoặc chỉ ngủ (1).

Có một tùy chọn tốt hơn.
Bạn chỉ có thể sử dụng semaphore, mà vẫn bị chặn ở đầu vòng lặp và bạn có thể báo hiệu semaphore bất cứ khi nào bạn muốn vòng lặp thực thi.
Lưu ý rằng điều này sẽ không ăn bất kỳ tài nguyên nào.

+1

"sẽ không ăn bất kỳ tài nguyên nào". Tạo một semaphore sử dụng tài nguyên hạt nhân và các đối tượng và là một hoạt động khá nặng. Đang chờ semaphore là một hoạt động chế độ hạt nhân và sẽ phải chuyển ngữ cảnh sang chế độ hạt nhân. –

+0

Một semaphore sẽ phù hợp nếu thời gian chờ được sử dụng, nhưng giấc ngủ vẫn có thể là tốt nhất. Semaphore có liên quan nhất nếu bạn muốn mã của bạn kích hoạt trên * hoặc * timeout * hoặc * một số sự kiện bên ngoài. –

+0

Cảm ơn bạn đã đề cập đến semaphore. Gotta khám phá rằng khi thời gian đến :) – resting

2

Câu trả lời ngắn gọn là có - loại bỏ giấc ngủ cho CPU 100% - nhưng câu trả lời phụ thuộc vào một số chi tiết bổ sung. Nó tiêu thụ tất cả CPU mà nó có thể nhận được, trừ khi ...

  1. Thân vòng lặp là tầm thường và được tối ưu hóa.
  2. Vòng lặp chứa hoạt động chặn (như một tệp hoặc hoạt động mạng). Liên kết bạn cung cấp đề xuất để tránh điều này, nhưng thường là một ý tưởng hay để chặn cho đến khi có điều gì đó có liên quan xảy ra.

EDIT: Trong trường hợp của bạn, tôi hỗ trợ đề xuất được thực hiện bởi @Als.

CHỈNH SỬA 2: Tôi hy vọng câu trả lời này đã nhận được -1 vì tôi cho rằng các hoạt động chặn thực sự có thể là một ý tưởng hay. [Nếu bạn -1, bạn nên để lại động lực trong một nhận xét để tất cả chúng ta có thể học được điều gì đó.]

Suy nghĩ phổ biến hiện tại là không chặn (dựa trên sự kiện) IO là tốt và chặn không tốt. Quan điểm này là đơn giản vì nó giả định tất cả các phần mềm thực hiện IO có thể cải thiện thông lượng bằng cách sử dụng các hoạt động không chặn.

Cái gì? Tôi thực sự gợi ý rằng việc sử dụng IO không chặn thực sự có thể làm giảm thông lượng không? Có, nó có thể. Khi một quá trình phục vụ một hoạt động duy nhất thì thực sự tốt hơn là sử dụng chặn IO vì việc chặn IO chỉ ghi các tài nguyên đã được trả tiền trong quá trình tồn tại.

Ngược lại, không chặn IO có thể mang chi phí cố định lớn hơn IO chặn đơn giản. Nếu quá trình không thể cung cấp thêm IO có thể được xen kẽ, thì không có gì đạt được bằng cách trả tiền cho thiết lập không bị chặn. (Trong thực tế, chi phí lớn nhất của IO không chặn không hợp nhất đơn giản là trong tính phức tạp của mã được thêm vào. Ngoài ra, chủ đề này chủ yếu là một bài tập tư duy.)

Theo chặn IO, chúng tôi dựa vào hệ điều hành để lên lịch các quy trình đó có thể tiến bộ. Đó là những gì hệ điều hành được thiết kế để làm.

Trong IO không chặn, chúng tôi có chi phí thiết lập lớn hơn nhưng có thể chia sẻ tài nguyên của quy trình và chủ đề của nó giữa công việc xen kẽ. IO không chặn là lý tưởng cho bất kỳ quá trình nào phục vụ cho nhiều hoạt động độc lập, chẳng hạn như máy chủ web. Thông lượng đạt được là vượt trội so với chi phí cố định chi phí của IO không chặn.

+0

Phần mềm có thể không cải thiện thông lượng bằng cách sử dụng không chặn I/O, nhưng nó luôn luôn cải thiện * đáp ứng *. Có, bạn nên chặn, nhưng nó phải là một cuộc gọi chặn chờ đợi cho một loạt các sự kiện, không phải là một cuộc gọi I/O chặn mà nguyên nhân đầu vào người dùng được bỏ qua cho đến khi I/O hoàn thành. 'select',' poll', 'aio_suspend' là tất cả các ví dụ. Bạn nói "Nếu quá trình không thể cung cấp thêm IO có thể xen kẽ", nhưng luôn có ít nhất một đầu vào bổ sung hơn có thể xảy ra ... yêu cầu người dùng thoát. –

+0

@BenVoigt Đúng vậy. Ứng dụng tương tác không được chặn vô thời hạn, ví dụ: một semaphore sau đó nên sử dụng một thời gian chờ. Điều đó nói rằng, dịch vụ phụ trợ posix có thể nhận tín hiệu ngay cả khi thực hiện một hoạt động chặn. Tất cả trong tất cả, bạn đã nêu ra một điểm tốt để nhớ - cảm ơn. –

13

Các cuộc gọi pollselect (đề cập bởi Basile trong câu trả lời) là cách chính xác để chờ yêu cầu, tùy theo hoàn cảnh. Trên các hệ điều hành không có poll hoặc select, sẽ có điều gì đó tương tự.

Không sleep, YieldProcessorsched_yield là những cách thích hợp để thực hiện việc này vì những lý do sau.

YieldProcessorsched_yield chỉ đơn thuần là di chuyển quá trình đến cuối hàng đợi có thể chạy được nhưng để nó chạy được. Hiệu ứng là chúng cho phép các quá trình khác có cùng mức ưu tiên hoặc cao hơn để thực hiện, nhưng khi các quá trình đó được thực hiện (hoặc nếu không có), thì quá trình gọi là YieldProcessor hoặc sched_yield tiếp tục chạy. Điều này gây ra hai vấn đề. Một là các quy trình ưu tiên thấp hơn vẫn sẽ không chạy. Khác là điều này làm cho bộ vi xử lý luôn chạy, sử dụng năng lượng. Chúng tôi muốn hệ điều hành nhận ra khi không có quá trình nào cần chạy và đưa bộ xử lý vào trạng thái công suất thấp.

sleep có thể cho phép trạng thái năng lượng thấp này, nhưng nó chơi trò chơi đoán sẽ kéo dài bao lâu cho đến khi yêu cầu tiếp theo đến, bộ xử lý sẽ liên tục xử lý khi không cần thiết. yêu cầu, vì quá trình sẽ tiếp tục ngủ cho đến khi hết thời gian yêu cầu ngay cả khi có yêu cầu được phục vụ.

Cuộc gọi pollselect được thiết kế cho chính xác tình huống này. Họ nói với hệ điều hành rằng quá trình này muốn phục vụ một yêu cầu đến trên một trong các kênh I/O của nó nhưng nếu không thì không có việc phải làm. Điều này cho phép hệ điều hành đánh dấu quá trình này là không chạy được và đặt bộ xử lý ở trạng thái công suất thấp nếu thích hợp.

Sử dụng semaphore cung cấp cùng một hành vi, ngoại trừ tín hiệu đánh thức quá trình đến từ quá trình khác nâng cao semaphore thay vì hoạt động phát sinh trong kênh I/O. Semaphores là phù hợp khi tín hiệu để làm một số công việc đến theo cách này; chỉ cần sử dụng bất kỳ số nào của poll hoặc semaphore phù hợp hơn với hoàn cảnh của bạn.

Những lời chỉ trích rằng poll, select hoặc semaphore khiến cuộc gọi chế độ hạt nhân không liên quan, vì các phương pháp khác cũng gây ra các cuộc gọi chế độ hạt nhân. Một quá trình không thể tự mình ngủ được; nó phải gọi hệ điều hành để yêu cầu nó. Tương tự, YieldProcessorsched_yield yêu cầu hệ điều hành.

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