2016-02-22 19 views
7

Trong Qt event loop, networking and I/O API talk của mình, Thiago Macieira đề cập rằng làm tổ của QEventLoop 's nên tránh:Tại sao nên lồng ghép QEventLoops?

QEventLoop được cho sự kiện tổ Loops ... Tránh nó nếu bạn có thể bởi vì nó tạo ra một số vấn đề: thứ có thể nhập lại , kích hoạt mới của ổ cắm hoặc bộ hẹn giờ mà bạn không mong đợi.

Ai có thể mở rộng về những gì anh ta đang đề cập đến không? Tôi duy trì rất nhiều mã sử dụng các hộp thoại phương thức mà nội bộ làm tổ một vòng lặp sự kiện mới khi exec() được gọi là vì vậy tôi rất quan tâm đến việc biết loại vấn đề này có thể dẫn đến.

Trả lời

8
  1. Vòng lặp sự kiện lồng nhau khiến bạn mất 1-2 nghìn ngăn xếp.

  2. Nó có khả năng nhập lại bất kỳ mã nào đã có trong ngăn xếp cuộc gọi. Không có gì đảm bảo rằng bất kỳ mã nào được thiết kế để được reentrant. Tôi đang nói về mã của bạn, không phải mã của Qt.

  3. Trong Qt hiện tại, có hai nơi, do từ lâu lỗi API hoặc bất cập nền tảng, bạn phải sử dụng lồng exec: QDrag và tập tin nền tảng các hộp thoại (trên một số nền tảng). Bạn chỉ đơn giản là không cần phải sử dụng nó ở bất cứ nơi nào khác. Bạn không cần vòng lặp sự kiện lồng nhau cho hộp thoại phương thức không thuộc nền tảng.

  4. Việc nhập lại vòng lặp sự kiện thường được gây ra bằng cách viết mã đồng bộ giả, nơi bạn than thở thiếu số yield(), ẩn đầu của bạn trên cát và sử dụng exec() thay thế. Mã như vậy thường kết thúc là spaghetti và không cần thiết. Viết mã không đồng bộ rõ ràng thường được thực hiện thông qua các máy trạng thái, xem this answer ví dụ và QP framework để triển khai khác với QStateMachine.

+0

Cảm ơn câu trả lời của bạn. Bạn có bất kỳ ý tưởng về "kích hoạt mới của ổ cắm hoặc giờ mà bạn không mong đợi"? – MuchToLearn

+0

@MuchToLearn Đó là ý nghĩa của việc nhập lại mã của bạn. Mã mà bạn gọi là 'exec' có thể, nói chung, được gọi lại. Nguồn của các sự kiện như vậy có thể là giao diện người dùng, nhưng nó có thể là bộ tính giờ, ổ cắm, sự kiện nền tảng gốc, v.v. –

+0

Máy trạng thái giống như một mô hình còn thiếu để bổ sung cho lập trình hướng đối tượng, chức năng và khai báo. – doc

0

Vòng lặp sự kiện lồng nhau sẽ dẫn đến đảo ngược thứ tự. (Ít nhất là trên qt4)

phép nói rằng bạn có trình tự sau đây của những điều xảy ra

enqueued in outer loop: 1,2,3 
processing 1 => spawn inner loop 
enqueue 4 in inner loop 
processing 4 
exit inner loop 
processing 2 

Vì vậy, bạn thấy đơn đặt hàng chế biến là: 1,4,2,3.

Tôi nói từ kinh nghiệm và điều này thường dẫn đến sự cố trong mã của tôi.

+0

Thú vị. Tôi cho rằng có một ràng buộc đặt hàng trong mã của bạn khiến mã đó bị lỗi? Bạn có thể đi sâu hơn vào chi tiết về loại sự kiện này không? Tôi không thấy một ưu tiên như thế nào enqueueing sự kiện 4 trong vòng lặp bên trong sẽ làm cho nó được xử lý đầu tiên hoặc sụp đổ mã của bạn. – MuchToLearn

+0

Tất nhiên mã dựa vào một số chuỗi tin nhắn. Một con trỏ sẽ được khởi tạo trên sự kiện đầu tiên và đối tượng được gọi vào sự kiện thứ hai và sự cố với lỗi seg. Đó là một điều hợp lệ để dựa vào đặt hàng nếu mọi thứ không phải là không đáng kể. – mhstnsc

+0

@MuchToLearn Điều này gần đây là một vấn đề trong nhóm của tôi khi có ai đó muốn tạo một yêu cầu HTTP và muốn đợi kết quả với vòng lặp bên trong. Cuối cùng anh ta định cư để chặn eventloop, đó là nếu nó không phải là UI, nếu không thì mọi thứ có thể lộn xộn bởi vì việc giới thiệu một bước không đồng bộ sẽ khá virus cho các API nhưng nếu bạn lấy qt, thì sẵn sàng trả giá :) – mhstnsc

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