首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在这种情况下,如何使多个python程序进行通信?

在这种情况下,如何使多个python程序进行通信?
EN

Stack Overflow用户
提问于 2016-05-16 01:39:52
回答 3查看 3.3K关注 0票数 4

我是Python的新手,我正在从事一个机器人项目。我问题的简短形式是,我正试图找到(针对我的情况)一次运行多个python程序的最佳方法。

有点上下文,我的机器人是一个服务机器人的平台,它能够使用图像算法跟踪标记和路径,还可以接收远程计算机的命令。我想有单独的程序,图像处理,驾驶等,然后通过一个主程序来管理它们。我知道我不能使用任何基本的东西,比如函数或类,因为每个进程必须是连续循环的,而且我不想将所有的代码组合在一个while循环中运行,因为它运行得非常慢,而且很难管理。

因此,简而言之,我如何使两个单独的,循环的程序“交谈”?就像我想让成像程序把它所看到的信息发送给驾驶和驾驶程序,等等。

我做了一些研究,我发现了一些关于多线程和API之类的信息,尽管我真的不知道哪一个是我要找的东西。

为了澄清,我只需要指出正确的方向。这似乎不是一个很高水平的事情,我知道那里肯定有教程,我只是真的很困惑从哪里开始,因为我正在教我自己。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-05-19 03:16:00

经过一番摸索后,我发现使用IPC是一个很好的解决方案。我使用的过程并不太困难,我只是做了一些非常简单的服务器和客户端类,并让它们通过本地主机IP进行通信。毫无疑问,有更好的方法可以做到这一点,但是对于像我这样的初学者来说,这是一种简单的方法,可以使两个程序在不修改代码的情况下说话。对于那些试图像我这样做类似事情的人,下面是我为自己做的课程。公平的警告,他们不是完全原始,甚至非常复杂,但他们完成了工作。

下面是我为服务器创建的类:

代码语言:javascript
复制
import socket
from random import random
from time import sleep

class ServerObject:

    def __init__(self,host_address,port):

        self._host_address = host_address
        self._s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self._s.bind((self._host_address,port))

    def handshake(self):

        print "Server Started. Awaiting Connection"

        while True: 
            _data, _addr = self._s.recvfrom(1024)
            if str(self._s.recvfrom(1024)[0]) == 'marco':
                break

        print 'marco recieved. sending polo...'

        while True:
            self._s.sendto('polo',_addr)
            if str(self._s.recvfrom(1024)[0]) == 'confirm':
                break
            sleep(.5)

        print 'connection verified'

        self._addr = _addr

        return True

    def send(self,data):

        self._s.sendto(str(data),self._addr)

    def recieve(self,mode = 0):

        _data, _addr = self._s.recvfrom(1024)

        if mode == 0:
            return str(_data)
        if mode == 1:
            return int(_data)
        if mode == 2:
            return float(_data)
        if mode == 3:
            return tuple(_data)

    def change_port(self,port):

        self._s.bind((self._host_address,port))

    def close(self):
        self._s.close()
        print '_socket closed_'


if __name__ == '__main__':

    host = '127.0.0.1'

    talk = ServerObject(host,6003)
    talk.handshake()

这是我为客户做的课程:

代码语言:javascript
复制
import socket
from time import sleep

class ClientObject:

    def __init__(self,host_address,server_port,port = 0):

        self._server = (host_address,server_port)
        self._s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self._s.bind((host_address,port))


    def handshake(self):

        print ' sending marco'

        self._s.sendto('marco',self._server)
        sleep(.1)
        self._s.sendto('marco',self._server)

        while True:
            if str(self._s.recvfrom(1024)[0]) == 'polo':
                break

        #self._s.sendto('marco',self._server)
        #self._s.sendto('marco',self._server)

        print ' connection verified'
        self._s.sendto('confirm',self._server)

        self._s.setblocking(0)

        return True

    def recieve(self,mode = 0):

        _data, _addr = self._s.recvfrom(1024)

        if mode == 0:
            return str(_data)
        if mode == 1:
            return int(_data)
        if mode == 2:
            return float(_data)
        if mode == 3:
            return tuple(_data)

    def send(self,data):
        self._s.sendto(str(data),self._server)

    def close(self):
        self._s.close()
        print '_socket closed_'


if __name__ == '__main__':

    host = '127.0.0.1'
    port = 0

    talk = ClientObject(host,24603,port)
    talk.handshake()

    #while True:
        #print talk.recieve()

在主要发送数据的程序上使用ServerObject类,在主要接收数据的程序上使用ClientObject类。在许多情况下,这些都可以翻转,但我发现最好这样做,以利用UDP。客户端类有一个可选端口变量,默认设置为0。这是因为对于UDP,客户端需要另一个端口来建立自己。0意味着它将选择一个可用端口,但是如果您指定了一个端口,那么如果客户端脱机而不需要重新启动两个程序,就可以重新建立连接。

首先对两个程序使用握手,确保使用相同的IP和端口(不引用客户端上的最后一个变量),然后使用发送和接收函数来回传递数据。

同样,这些都不是很好,事实上,使用这种方法会产生很多问题,但是对于一个简单的任务,他们完成了任务。我将握手设置为打印正在发生的事情的验证,但如果这些内容变得烦人,您只需删除这些行即可。

希望这能有所帮助!

票数 1
EN

Stack Overflow用户

发布于 2016-05-16 01:52:54

我认为多加工库可能是一个解决方案。当每个进程都可以执行特定的工作时,您将能够并行运行多个进程,同时将数据发送给对方。

您可以检查这个示例

这是泛型目录遍历器,它具有扫描目录树的进程,并将数据传递给其他进程,后者扫描已经发现的文件夹中的文件。所有这些都是并行完成的。

票数 1
EN

Stack Overflow用户

发布于 2016-06-05 14:56:55

这可能超出了项目的范围,但是您考虑过使用ROS吗?它允许您同时运行多个不同的节点(可以是Python脚本),它们通过发布和订阅主题进行通信。它们可以位于同一个系统(即机器人上的一个或多个节点)或不同的系统(即机器人上的一个节点,PC上的多个节点)。ROS还有很多很棒的工具和库,专门用于机器人系统,如可视化、映射、测定仪等。以下是一些开始的信息:

系统

http://wiki.ros.org/ROS/StartGuide

它通常用于比您所描述的要大得多的框架,要注意,实现它需要相当长的时间(在我的经验中),但是一旦它启动和运行,就很容易扩展。就像我说的,这都取决于你的项目的范围!

祝好运!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37245559

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档