回答
這聽起來像ZeroMQ代碼要簡單地被執行了一遍又一遍,儘可能多。最簡單的方法是將ZeroMQ代碼放入空閒函數或超時函數中,並使用非阻塞版本的函數(如果存在)。
雜波,你會使用clutter_threads_add_idle()
或clutter_threads_add_timeout()
。對於GTK,您可以使用g_idle_add()
或g_timeout_add()
。
更困難但可能更好的方法是使用g_thread_create()
爲ZeroMQ代碼創建一個單獨的線程,並且只使用while(1)
構造和阻塞函數。如果你這樣做了,你還必須找到一些線程相互通信的方式--GLib的互斥鎖和異步隊列通常都可以。
我發現有一個叫Zeromqt QT集成庫。望着源,一體化的核心是:
ZmqSocket::ZmqSocket(int type, QObject *parent) : QObject(parent)
{
...
notifier_ = new QSocketNotifier(fd, QSocketNotifier::Read, this);
connect(notifier_, SIGNAL(activated(int)), this, SLOT(activity()));
}
...
void ZmqSocket::activity()
{
uint32_t flags;
size_t size = sizeof(flags);
if(!getOpt(ZMQ_EVENTS, &flags, &size)) {
qWarning("Error reading ZMQ_EVENTS in ZMQSocket::activity");
return;
}
if(flags & ZMQ_POLLIN) {
emit readyRead();
}
if(flags & ZMQ_POLLOUT) {
emit readyWrite();
}
...
}
因此,它是依靠QT的集成插座處理和雜波不會有類似的東西。
您可能還想看看[nzmqt](https://github.com/jonnydee/nzmqt) - ZeroMQ的另一個Qt綁定。你會發現一個基於輪詢的實現。特別要看看班級[PollingZMQSocket(line 429 ++)](https://github.com/jonnydee/nzmqt/blob/7f3c54c2d3055769df157d01319a333d61cba1f1/include/nzmqt/nzmqt.hpp#L497)。也許你可以爲Clutter做些類似的事情。 –
你可以得到0MQ插座(ZMQ_FD選項)文件描述符和整合,以你的事件循環。我認爲gtk有一些處理套接字的機制。
到ZMQ和GTK或雜波相結合的正確方法是將ZMQ隊列的文件描述符連接到主事件循環。在FD可以通過使用
int fd;
size_t sizeof_fd = sizeof(fd);
if(zmq_getsockopt(socket, ZMQ_FD, &fd, &sizeof_fd))
perror("retrieving zmq fd");
它連接到主循環使用io_add_watch此事進行檢索:
GIOChannel* channel = g_io_channel_unix_new(fd);
g_io_add_watch(channel, G_IO_IN|G_IO_ERR|G_IO_HUP, callback_func, NULL);
在回調函數,就必須先檢查是否有真的東西在閱讀之前閱讀。否則,該功能可能會阻止等待IO。
gboolean callback_func(GIOChannel *source, GIOCondition condition,gpointer data)
{
uint32_t status;
size_t sizeof_status = sizeof(status);
while (1){
if (zmq_getsockopt(socket, ZMQ_EVENTS, &status, &sizeof_status)) {
perror("retrieving event status");
return 0; // this just removes the callback, but probably
// different error handling should be implemented
}
if (status & ZMQ_POLLIN == 0) {
break;
}
// retrieve one message here
}
return 1; // keep the callback active
}
請注意:這是沒有實際測試過,我做了一個翻譯用Python +雜波,這是我用,但我敢肯定它會工作。 僅供參考,下面是完整的Python + Clutter代碼,其實際工作。
import sys
from gi.repository import Clutter, GObject
import zmq
def Stage():
"A Stage with a red spinning rectangle"
stage = Clutter.Stage()
stage.set_size(400, 400)
rect = Clutter.Rectangle()
color = Clutter.Color()
color.from_string('red')
rect.set_color(color)
rect.set_size(100, 100)
rect.set_position(150, 150)
timeline = Clutter.Timeline.new(3000)
timeline.set_loop(True)
alpha = Clutter.Alpha.new_full(timeline, Clutter.AnimationMode.EASE_IN_OUT_SINE)
rotate_behaviour = Clutter.BehaviourRotate.new(
alpha,
Clutter.RotateAxis.Z_AXIS,
Clutter.RotateDirection.CW,
0.0, 359.0)
rotate_behaviour.apply(rect)
timeline.start()
stage.add_actor(rect)
stage.show_all()
stage.connect('destroy', lambda stage: Clutter.main_quit())
return stage, rotate_behaviour
def Socket(address):
ctx = zmq.Context()
sock = ctx.socket(zmq.SUB)
sock.setsockopt(zmq.SUBSCRIBE, "")
sock.connect(address)
return sock
def zmq_callback(queue, condition, sock):
print 'zmq_callback', queue, condition, sock
while sock.getsockopt(zmq.EVENTS) & zmq.POLLIN:
observed = sock.recv()
print observed
return True
def main():
res, args = Clutter.init(sys.argv)
if res != Clutter.InitError.SUCCESS:
return 1
stage, rotate_behaviour = Stage()
sock = Socket(sys.argv[2])
zmq_fd = sock.getsockopt(zmq.FD)
GObject.io_add_watch(zmq_fd,
GObject.IO_IN|GObject.IO_ERR|GObject.IO_HUP,
zmq_callback, sock)
return Clutter.main()
if __name__ == '__main__':
sys.exit(main())
請注意,對於io_add_watch回調而言,重要的是必須返回True。沒有這個,回調只會被調用一次。 –
這是Python中的一個例子,使用PyQt4。它來源於一個工作應用程序。
import zmq
from PyQt4 import QtCore, QtGui
class QZmqSocketNotifier(QtCore.QSocketNotifier):
""" Provides Qt event notifier for ZMQ socket events """
def __init__(self, zmq_sock, event_type, parent=None):
"""
Parameters:
----------
zmq_sock : zmq.Socket
The ZMQ socket to listen on. Must already be connected or bound to a socket address.
event_type : QtSocketNotifier.Type
Event type to listen for, as described in documentation for QtSocketNotifier.
"""
super(QZmqSocketNotifier, self).__init__(zmq_sock.getsockopt(zmq.FD), event_type, parent)
class Server(QtGui.QFrame):
def __init__(self, topics, port, mainwindow, parent=None):
super(Server, self).__init__(parent)
self._PORT = port
# Create notifier to handle ZMQ socket events coming from client
self._zmq_context = zmq.Context()
self._zmq_sock = self._zmq_context.socket(zmq.SUB)
self._zmq_sock.bind("tcp://*:" + self._PORT)
for topic in topics:
self._zmq_sock.setsockopt(zmq.SUBSCRIBE, topic)
self._zmq_notifier = QZmqSocketNotifier(self._zmq_sock, QtCore.QSocketNotifier.Read)
# connect signals and slots
self._zmq_notifier.activated.connect(self._onZmqMsgRecv)
mainwindow.quit.connect(self._onQuit)
@QtCore.pyqtSlot()
def _onZmqMsgRecv():
self._test_info_notifier.setEnabled(False)
# Verify that there's data in the stream
sock_status = self._zmq_sock.getsockopt(zmq.EVENTS)
if sock_status == zmq.POLLIN:
msg = self._zmq_sock.recv_multipart()
topic = msg[0]
callback = self._topic_map[ topic ]
callback(msg)
self._zmq_notifier.setEnabled(True)
self._zmq_sock.getsockopt(zmq.EVENTS)
def _onQuit(self):
self._zmq_notifier.activated.disconnect(self._onZmqMsgRecv)
self._zmq_notifier.setEnabled(False)
del self._zmq_notifier
self._zmq_context.destroy(0)
禁用,然後重新啓用通知在_on_ZmqMsgRecv
是每對QSocketNotifier的文檔。
對於getsockopt的最終調用是有必要的。否則,通知程序在第一個事件之後停止工作。實際上我會爲此發佈一個新問題。有誰知道爲什麼這是必要的?
請注意,如果你不破壞ZMQ上下文之前發出通知,你可能會當您退出應用程序獲得類似這樣的錯誤:
QSocketNotifier: Invalid socket 16 and type 'Read', disabling...
- 1. 在aiohttp應用程序中收聽ZeroMQ
- 2. 如何使用ZeroMQ喚醒線程
- 3. 嵌入式應用程序中的「Erlang」與「zeromq +任何語言」
- 4. 使用ZeroMQ從線程中調用系統()使用ZeroMQ時的線程
- 5. 刪除WebRTC並在Android應用程序中添加zeroMQ
- 6. 如何使用zeromq對AWS
- 7. 在VS2012中使用ZeroMQ C++
- 8. 在excel/vba中使用zeromq
- 9. 如何使用在Web應用程序
- 10. 如何在C#.net桌面應用程序中使用VC++應用程序
- 11. 如何在現有應用程序中使用django-scheduler應用程序
- 12. 如何使用Objective-C在Mac應用程序中運行應用程序?
- 13. 在Android應用程序中使用libusb:如何讓應用程序訪問USB
- 14. 如何在我的Android應用程序中使用Printershare應用程序
- 15. VS2013 Cordova應用程序,如何在移動應用程序中使用* .less?
- 16. 如何在單個應用程序中使用多個應用程序? Objective C
- 17. 如何在Padrino應用程序中安裝Sinatra應用程序?
- 18. 如何在ajax應用程序中加載Angularjs應用程序?
- 19. 如何使用Maven在RCP應用程序中使用log4j?
- 20. 如何使用resclientemozilla發送應用程序的應用程序?
- 21. 如何在UIWebView中使用Apple(在應用程序中購買)?
- 22. 如何在JSP中使用SSL(在Java EE應用程序中)?
- 23. 如何在多線程應用程序中使用aiopg池?
- 24. 如何在多線程應用程序中使用Timer
- 25. 如何在多線程應用程序中有效使用RestTemplate?
- 26. 如何在iOS應用程序中使圖像變成全屏應用程序
- 27. 在Xamarin應用程序中使用圖像應用程序
- 28. 在ASP.NET應用程序中使用應用程序變量
- 29. 在Tomcat應用程序中使用Apache的應用程序
- 30. 在我的Android應用程序中使用Maps應用程序
會在空閒定時器,結果不投票zeromq在100%的CPU使用率? –
在一個空閒函數中,可能是的,至少當GTK主循環沒有做其他事情時。在超時功能中,不。 – ptomato