2017-10-05 14 views
5

Theo bài viết sau, tín hiệu phát ra được phục vụ, chỉ khi khe đang thực hiện hoàn thành.
Wait for a SLOT to finish the execution with QtTại sao một tín hiệu mới cho socket :: readyRead() được thực hiện, ngay cả khi khe trước đó của nó vẫn đang xử lý?

Tôi có ứng dụng truyền thông máy khách-máy chủ dựa trên ổ cắm ssl, là một luồng đơn.

connect(socket, &QSslSocket::readyRead, [&]() { myObject.Read(); }); 

Máy khách & máy chủ gửi cho nhau một số thông điệp tùy chỉnh. Bất cứ khi nào một tin nhắn được gửi hoặc nhận bởi một trong hai, họ gửi ACK byte (00).
Hầu hết các lần, tôi nhận thấy rằng khi Read() nằm trong khoảng thời gian thực thi, readyRead() được phục vụ tiếp theo! Tôi đặt các câu lệnh gỡ lỗi vào đầu & kết thúc của myObject->Read(). Họ xác nhận rằng, bắt đầu gỡ lỗi lại được gọi lại là &. Cùng được quan sát với các điểm ngắt.

Khi nhận được quá nhiều dữ liệu, khung ngăn xếp đệ quy được tạo quá nhiều Read() s. Nó hoặc làm chậm giao diện ứng dụng hoặc treo.
Thông thường đệ quy này xảy ra, khi khách hàng tìm cách gửi ACK như một phần của myObject->Read(). Trong thời gian đó, readyRead() được báo hiệu tình cờ & cũng được phân phối. Tuy nhiên, khe của tín hiệu trước đó vẫn đang được xử lý.

Câu hỏi:

  • Có thể cho khung Qt để phục vụ một tín hiệu ở giữa khi một khe cắm vẫn là giữa đường (chủ đề duy nhất)?
  • Cách khắc phục tình huống cụ thể của socket này?

Note:
- Theo mặc định cho chủ đề duy nhất, Qt::ConnectionTypeDirectConnection. Tôi đã thử với QueuedConnection là tốt, nhưng kết quả là như nhau.
- myObject.Read() khá phức tạp và có nhiều cuộc gọi chức năng khác. Nếu điều này gây ra sự cố, hãy cho tôi biết tôi nên tìm kiếm điều gì. Sẽ không thực tế khi viết mã thực sự của nó.

+1

Có thể giúp https://stackoverflow.com/questions/11230080/qobject-based-class-has-a-queued-connection-to-itself –

+0

Nếu 'myObject-> Read()' được gọi trong khi bạn đã có trong nó, có khả năng là bạn có một lúc nào đó được kiểm soát vòng lặp sự kiện. Bạn có thể thêm mã của hàm không? –

+0

@ BenjaminT, có rất nhiều thứ không liên quan đến Qt nhưng chức năng cốt lõi bên trong phương thức 'Read()'. Sẽ không thực tế khi viết mã đó vì có một số phương thức bên trong đó. Tuy nhiên, làm thế nào là nó có thể cho một vòng lặp sự kiện có thể kiểm soát khi một khe vẫn còn đang được thực hiện? Bạn có thể gợi ý, trong đó có cách nào là có thể. Có thể tôi có thể thử nhìn những thứ đó. – iammilind

Trả lời

2

Cuộc gọi đệ quy readyRead() đã xảy ra do vòng lặp sự kiện được giải phóng ở giữa. chức năng sau đã gây ra vòng lặp sự kiện để được giải phóng:

  1. QCoreApplication::processEvents()
  2. SslSocket::flush()

The 1st là điều dễ hiểu, vì nó có nghĩa là cho điều đó. Tuy nhiên, flush() thứ hai là một bất ngờ hoàn toàn. Số documentation của nó không phát biểu. Ít nhất là trong gỡ lỗi của tôi nó đã được hiển thị rằng, bất cứ khi nào flush() được gọi, sau readyRead() được gọi và phục vụ. Thấy rằng trong Qn là tốt.

processEvent() có nghĩa là làm cho GUI trở nên nhạy hơn trong quá trình tải dữ liệu cao. Nhưng có vẻ như, chúng ta cần phải thực hiện một lựa chọn khác cho tương tự.

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