2009-08-12 27 views
30

Tôi không chắc chắn về bản chất của cơ chế tín hiệu/khe trong Qt 4.5. Khi một tín hiệu được phát ra, đó có phải là một cuộc gọi chức năng chặn hoặc một luồng không? Hãy nói điều nàyQt 4.5 - Phát ra tín hiệu một cuộc gọi chức năng, hoặc một luồng, và nó có chặn không?

emit GrabLatestData(); 

// proceed with latest data 

Tất cả chuỗi tín hiệu/khe có được giải quyết trước khi tiếp tục sang dòng tiếp theo không?

Trả lời

41

Điều đó tùy thuộc. Từ số documentation:

Khi tín hiệu được phát ra, các vị trí được kết nối với nó thường được thực hiện ngay lập tức, giống như cuộc gọi chức năng bình thường. Khi điều này xảy ra, cơ chế tín hiệu và khe là hoàn toàn độc lập với bất kỳ vòng lặp sự kiện GUI nào. Việc thực thi mã theo sau câu lệnh emit sẽ xảy ra khi tất cả các vị trí đã trả lại. Tình huống hơi khác khi sử dụng queued connections; trong trường hợp này, mã theo từ khóa phát ra sẽ tiếp tục ngay lập tức và các vị trí sẽ được thực hiện sau đó.

Vì vậy, trong trường hợp bình thường, nó sẽ đồng bộ và chặn và kết nối hàng đợi sẽ không đồng bộ và không bị chặn.

+10

Cũng lưu ý rằng theo mặc định: kết nối giữa các đối tượng trong cùng một luồng là trực tiếp (đồng bộ) và kết nối giữa các đối tượng trong các chuỗi khác nhau được xếp hàng đợi. Nếu bạn nghĩ về nó khá hợp lý. – quark

+0

@quark Đó không chính xác. Nó không quan trọng nếu các đối tượng trong cùng một chủ đề hay không. Nó quan trọng nếu thread phát ra tín hiệu là luồng mà đối tượng nhận đang ở trong đó. Tài liệu Qt thậm chí còn nhận được lỗi này.Nguồn: [Tín hiệu và vị trí trên các chủ đề] (http://qt-project.org/wiki/Threads_Events_QObjects#913fb94dd61f1a62fc809f8d842c3afa). Tôi đồng ý rằng hành vi của Qt là hợp lý. –

9

câu trả lời của laalto ở trên là chính xác. Một điểm nữa là: nếu tất cả các QObject của bạn thuộc cùng một luồng và bạn chưa xác định các kết nối được xếp hàng theo cách thủ công, thì việc thực hiện các khe được kết nối với tín hiệu xảy ra đồng bộ - tất cả xử lý sẽ được thực hiện trước dòng tiếp theo sau 'phát ra ' tuyên bố. Vì đây là trường hợp phổ biến nhất, câu trả lời cho câu hỏi của bạn thường là 'có'.

Tài liệu trên signals and slots across multiple threads có thể hữu ích cho bạn.

25

Vấn đề lớn nhất là bạn không thể biết. Đó là, nếu bạn đang nhìn từ quan điểm của lớp. Khi bạn phát ra, bạn không biết những gì sẽ xảy ra:

  • Nếu không có ai được kết nối với tín hiệu, không có gì xảy ra
  • Nếu ai đó từ cùng một sợi được kết nối sử dụng bất kỳ loại trừ Qt :: QueuedConnection, cuộc gọi sẽ chặn
  • Nếu ai đó từ cùng một chuỗi được kết nối bằng Qt :: QueuedConnection, cuộc gọi sẽ không bị chặn
  • Nếu ai đó từ một chủ đề khác được kết nối bằng Qt :: DirectConnection (phải hết sức cẩn thận khi bạn làm điều đó!) hoặc Qt :: BlockingQueuedConnection, cuộc gọi sẽ chặn
  • Nếu một người nào đó từ một chủ đề khác được kết nối bằng Qt :: AutoConnection hoặc Qt :: QueuedConnection, cuộc gọi sẽ không bị chặn

Sẽ khó khăn hơn nếu biết nhiều điều sẽ xảy ra nếu nhiều đối tượng được kết nối với tín hiệu. Trong trường hợp đó, một số vị trí có thể chạy trong khi các vị trí khác vẫn được xếp hàng đợi. Có, bằng cách này, không có chủ đề liên quan đến một kết nối không chặn. Chỉ có một sự kiện được đăng trong vòng lặp sự kiện của chuỗi của đối tượng nhận.

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