Tôi đang tạo một công cụ trò chơi 2D đơn giản và tôi muốn cập nhật và kết xuất các họa tiết trong các luồng khác nhau, để tìm hiểu cách thực hiện.
Tôi cần phải đồng bộ hóa luồng cập nhật và kết xuất. Hiện tại, tôi sử dụng hai lá cờ nguyên tử. Quy trình làm việc trông giống như:
Thread 1 -------------------------- Thread 2
Update obj ------------------------ wait for swap
Create queue ---------------------- render the queue
Wait for render ------------------- notify render done
Swap render queues ---------------- notify swap done
Trong thiết lập này, tôi giới hạn FPS của luồng kết xuất ở FPS của luồng cập nhật. Ngoài ra, tôi sử dụng sleep()
để giới hạn cả kết xuất và cập nhật FPS của luồng thành 60, vì vậy hai chức năng chờ sẽ không phải chờ nhiều thời gian.
Vấn đề là:
Mức sử dụng CPU trung bình là khoảng 0,1%. Đôi khi, nó lên tới 25% (trong PC lõi tứ). Điều đó có nghĩa là một luồng đang chờ chuỗi khác vì hàm chờ là vòng lặp while có chức năng kiểm tra và thiết lập và vòng lặp while sẽ sử dụng tất cả tài nguyên CPU của bạn.
Câu hỏi đầu tiên của tôi là: có cách nào khác để đồng bộ hóa hai luồng không? Tôi nhận thấy rằng std::mutex::lock
không sử dụng CPU trong khi nó đang chờ khóa tài nguyên để nó không phải là vòng lặp while. Làm thế nào nó hoạt động? Tôi không thể sử dụng std::mutex
vì tôi sẽ cần khóa chúng trong một chuỗi và mở khóa trong một luồng khác.
Câu hỏi khác là; vì chương trình luôn chạy ở tốc độ 60 FPS, tại sao đôi khi mức sử dụng CPU của nó tăng vọt lên 25%, có nghĩa là một trong hai chờ đợi đang chờ đợi rất nhiều? (cả hai luồng đều bị giới hạn ở 60 khung hình / giây nên lý tưởng là chúng không cần nhiều sự đồng bộ hóa).
Chỉnh sửa: Cảm ơn tất cả các câu trả lời. Đầu tiên tôi muốn nói rằng tôi không bắt đầu một chủ đề mới mỗi khung hình để kết xuất. Tôi bắt đầu cả vòng lặp cập nhật và kết xuất lúc đầu. Tôi nghĩ rằng đa luồng có thể tiết kiệm thời gian: Tôi có các chức năng sau: FastAlg () và Alg (). Alg () là cả obj Cập nhật của tôi và kết xuất obj và Fastache () là "gửi hàng đợi kết xuất tới" trình kết xuất "" của tôi. Trong một chủ đề duy nhất:
Alg() //update
FastAgl()
Alg() //render
Trong hai chủ đề:
Alg() //update while Alg() //render last frame
FastAlg()
Vì vậy, có thể đa luồng có thể tiết kiệm cùng thời gian. (thực ra trong một ứng dụng toán học đơn giản, trong đó alg là một thuật toán dài, nhanh hơn một thuật toán nhanh hơn)
Tôi biết rằng giấc ngủ không phải là một ý tưởng tốt, mặc dù tôi không bao giờ có vấn đề. Điều này sẽ tốt hơn?
While(true)
{
If(timer.gettimefromlastcall() >= 1/fps)
Do_update()
}
Nhưng đây sẽ là một vòng lặp vô hạn trong đó sẽ sử dụng tất cả CPU. Tôi có thể sử dụng chế độ ngủ (số <15) để hạn chế việc sử dụng không? Theo cách này, nó sẽ chạy ở tốc độ 100 khung hình / giây và chức năng cập nhật sẽ được gọi chỉ 60 lần mỗi giây.
Để đồng bộ hóa hai luồng, tôi sẽ sử dụng Waitforsingleobject với createSemaphore để tôi có thể khóa và mở khóa trong các luồng khác nhau (xóa trắng bằng vòng lặp while), phải không?