2010-09-16 48 views
36

Tôi đã từng xem Sleep(0) trong một số phần của mã của tôi, nơi có sẵn một số vòng lặp vô hạn/dài while. Tôi đã được thông báo rằng nó sẽ làm cho các lát thời gian có sẵn cho các quá trình chờ đợi khác. Điều này có đúng không? Có ý nghĩa gì đối với Sleep(0) không?Tầm quan trọng của giấc ngủ (0)

+2

Với C++ 11, bạn có một nền tảng độc lập tốt hơn để làm điều đó: ['std :: this_thread :: yield()'] (http://en.cppreference.com/w/cpp/thread/ năng suất)! – iammilind

Trả lời

37

Theo tài liệu MSDN cho Sleep:

Một giá trị không gây ra các chủ đề để bỏ phần còn lại của thời gian lát của mình cho bất kỳ chủ đề khác đó là sẵn sàng để chạy. Nếu không có các chủ đề khác sẵn sàng chạy, hàm sẽ trả về ngay lập tức và luồng tiếp tục thực hiện.

Điều quan trọng cần nhận ra là có, điều này mang lại cho chủ đề khác một cơ hội để chạy, nhưng nếu có không sẵn sàng để chạy, sau đó chủ đề của bạn tiếp tục - bỏ việc sử dụng CPU 100% kể từ một cái gì đó sẽ luôn chạy. Nếu vòng lặp while của bạn chỉ quay trong khi chờ đợi một số điều kiện, bạn có thể muốn xem xét sử dụng đồng bộ nguyên thủy như một sự kiện để ngủ cho đến khi điều kiện được thỏa mãn hoặc ngủ trong một khoảng thời gian ngắn để tránh tối đa CPU.

17

Có, nó mang lại cho các chủ đề khác cơ hội để chạy.

Một giá trị không gây ra các chủ đề để bỏ phần còn lại của thời gian lát của mình cho bất kỳ chủ đề khác đó là sẵn sàng để chạy. Nếu không có các chủ đề khác sẵn sàng chạy, hàm sẽ trả về ngay lập tức và luồng tiếp tục thực hiện.

Source

14

Tôi sợ rằng tôi không thể cải thiện trên MSDN docs đây

Một giá trị không gây ra các chủ đề để bỏ phần còn lại của thời gian lát của mình cho bất kỳ khác chuỗi là sẵn sàng để chạy. Nếu không có các chủ đề khác sẵn sàng chạy, hàm sẽ trả về ngay lập tức và luồng tiếp tục thực hiện.

Windows XP/2000: Giá trị zero gây thread từ bỏ thời gian còn lại lát của mình cho bất kỳ thread khác ưu tiên bình đẳng đó là sẵn sàng để chạy. Nếu không có các chủ đề khác của có mức độ ưu tiên bằng nhau sẵn sàng để chạy, hàm trả về ngay lập tức, và chuỗi tiếp tục thực hiện. hành vi này đã thay đổi bắt đầu với Windows Server 2003.

hãy cũng lưu ý (thông qua phiếu bầu tán thành) hai câu trả lời hữu ích liên quan đến vấn đề hiệu quả ở đây.

13

Hãy cẩn thận với chế độ Ngủ (0), nếu thời gian thực hiện lặp lại một vòng ngắn, điều này có thể làm chậm đáng kể vòng lặp đó.Nếu điều này là quan trọng để sử dụng nó, bạn có thể gọi Sleep (0), ví dụ, một lần cho mỗi 100 lần lặp.

+2

Tôi không thấy làm thế nào nó có thể có ý nghĩa để đặt một giấc ngủ (0) trong một vòng lặp mà cũng được coi là nhanh. – sellibitze

+0

sellibitze: Ý tôi là, một lần lặp lại nhanh và không phải toàn bộ vòng lặp. –

+0

@sellibitze: Hãy xem xét lai ngủ/bận-chờ đợi. Điều này khá phổ biến đối với mã thời gian quan trọng không cần nhiệm vụ mà không muốn hog CPU, mặc dù heuristic thường là thứ phức tạp hơn như chỉ ngủ nếu bạn mong đợi thời hạn lặp lại tiếp theo> n-nhiều ms trong tương lai . –

1

Ngủ (0) là công cụ mạnh mẽ và có thể cải thiện hiệu suất trong một số trường hợp nhất định. Sử dụng nó trong một vòng lặp nhanh có thể được xem xét trong trường hợp đặc biệt. Khi một tập hợp các chủ đề được đáp ứng tối đa, tất cả chúng sẽ sử dụng Sleep (0) thường xuyên. Nhưng nó là điều tàn nhẫn để tìm một người cai trị cho những gì có nghĩa là đáp ứng trong bối cảnh của mã.

Tôi đã đưa ra một số chi tiết trong https://stackoverflow.com/a/11456112/1504523

2

Sleep(0); Tại hướng dẫn rằng, hệ thống lên lịch sẽ kiểm tra đối với bất kỳ chủ đề Runnable khác và có thể cung cấp cho họ một cơ hội để sử dụng tài nguyên hệ thống tùy thuộc vào các ưu tiên chủ đề.

Trên Linux có một lệnh cụ thể cho việc này: sched_yield() như từ các trang người đàn ông:

sched_yield() gây tiểu trình đang gọi nhường CPU. Chủ đề được di chuyển đến cuối hàng đợi để có mức độ ưu tiên tĩnh của nó và một chủ đề mới được chạy là .

Nếu chuỗi cuộc gọi là chuỗi duy nhất trong danh sách ưu tiên cao nhất tại thời điểm đó, nó sẽ tiếp tục chạy sau khi gọi đến sched_yield().

với cũng

cuộc gọi chiến lược để sched_yield() có thể cải thiện hiệu suất bằng cách cho đề khác hoặc xử lý một cơ hội để chạy khi (nặng) tranh luận nguồn lực (ví dụ, mutexes) đã được phát hành bởi người gọi . Tránh gọi sched_yield() không cần thiết hoặc không thích hợp (ví dụ: khi tài nguyên cần thiết bởi các chuỗi lịch khác vẫn được giữ bởi người gọi ), vì làm như vậy sẽ dẫn đến các công tắc ngữ cảnh không cần thiết, .

+0

Và trong Windows, chúng ta có 'SwitchToThread()' –

0

Tôi đang sử dụng bằng cách sử dụng pthread và vì một số lý do trên mac của tôi trình biên dịch không tìm thấy pthread_yield() được khai báo. Nhưng có vẻ như giấc ngủ (0) cũng giống nhau.

1

Trong một ứng dụng .... chuỗi chính tìm kiếm những việc cần làm, sau đó khởi chạy "công việc" qua một chuỗi mới. Trong trường hợp này, bạn nên gọi sched_yield() (hoặc ngủ (0)) trong chủ đề chính, do đó, bạn không làm cho "tìm kiếm" cho công việc, quan trọng hơn sau đó là "công việc". Tôi thích ngủ (0), nhưng đôi khi điều này là quá nhiều (vì bạn đang ngủ một phần nhỏ của một giây).

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