1

I'm using zmq on a computer (python) to communicate with a robot (c++) using zmq. The communication works most of the time but is then interrupted by an interrupted system call error after some time (no exact point in time).

Python: to connect

self.context = zmq.Context()
self.stateSocket = self.context.socket(zmq.REQ)
self.failCounter = 0
self.poll = zmq.Poller()
try:
    self.stateSocket = self.context.socket(zmq.REQ)
    self.stateSocket.connect(self.connectString)
    self.poll.register(self.stateSocket, zmq.POLLIN)
    self.timer.start()
except zmq.ZMQError as e:
    print("Connection to socket not possible: ", e)
    

to communicate looping in a QTTimer:

retries_left = 2
        while retries_left:
            request = #data here
            self.stateSocket.send_string(request, zmq.NOBLOCK)

            expect_reply = True
            while expect_reply:
                socks = dict(self.poll.poll(400))
                if socks.get(self.stateSocket) == zmq.POLLIN:
                    message = self.stateSocket.recv()
                    if not message:
                        break
                    expect_reply = False
                    retries_left = 0
                    self.receivedValues = [float(i) for i in message.decode("UTF-8").split(',')]

                    self.dataAnalysis() #do stuff with received values


                else:
                    print("W: No response from server, retrying ...")
                    # Socket is confused. Close and remove it.
                    self.stateSocket.setsockopt(zmq.LINGER, 0)
                    self.stateSocket.close()
                    self.poll.unregister(self.stateSocket)
                    retries_left -= 1
                    if retries_left == 0:
                        print("E: Server seems to be offline, abandoning")
                        break
                    else:
                        print("I: Reconnecting and resending ")
                        # Create new connection
                        self.stateSocket = self.context.socket(zmq.REQ)
                        self.stateSocket.connect(self.connectString)
                        self.poll.register(self.stateSocket, zmq.POLLIN)
                        self.stateSocket.send_string(request)

and the cpp part:

//setup
zmq::context_t context{ 1 };
zmq::socket_t socket{ context, ZMQ_REP };
const std::chrono::milliseconds timeout{ 400 };
zmq::pollitem_t pollItem[1];
zmq::message_t receivedData;
    try
    {
        int rc = zmq::poll(pollItem, 1, 400);
        if (rc < 0)
        {
            std::cout << "No data available" << std::endl;
        }
        else 
        {
            socket.recv(receivedData, zmq::recv_flags::dontwait);
        }

        zmq::message_t reply{ replyString.cbegin(), replyString.cend() };
        socket.send(reply, zmq::send_flags::dontwait);
    }
    catch (zmq::error_t& e)
    {
        std::cout << "Sending Error: " << e.what() << std::endl;
    }

This runs for 30+ seconds and then the cpp part throws an Interrupted system call error. From what I have read this means something is blocking but I can't figure out what might be the issue. Can anyone figure out what I'm doing wrong?

FR_MPI
  • 111
  • 1
  • 9
  • Most (all?) system calls can be interrupted when a _signal_ is raised. Signals can be raised for various reasons. You should run the C++ program under a debugger, such as [gdb](https://sourceware.org/gdb/current/onlinedocs/gdb/Signals.html), to see what signal is raised and when and where. – rveerd Jun 15 '21 at 11:23
  • 1
    Are you, for example, using some kind of alarm or timer functionality? These can raise SIGALRM. – rveerd Jun 15 '21 at 11:26
  • I'm not using any alarms. The code you see is all that is running in this thread – FR_MPI Jul 20 '21 at 12:38
  • @rveerd I've encountered conflict between SIGLARM and ZMQ, so I retry zmq if SIGALRM is raised. what is the best handling SIGLARM with ZMQ? – ImJa Apr 03 '22 at 00:41

0 Answers0