python服务器中进程之间共享列表

2024-04-24

我有简单的UDP服务器,它适用于多重处理.

我想创建一个列表,其中包含有关所有客户的信息。

I use Manager,但我不明白,如何在列表中附加信息 - 我需要传输 Manager 的对象来处理,但是如何?我使用新属性的方法不起作用。

import multiprocessing
from socketserver import UDPServer, ForkingMixIn, DatagramRequestHandler
from socket import socket, AF_INET, SOCK_DGRAM
from settings import host, port, number_of_connections

class ChatHandler(DatagramRequestHandler):

    def handle(self):
        cur_process = multiprocessing.current_process()
        data = self.request[0].strip()
        socket = self.request[1]
        ChatHandler.clients.append(self.client_address) # error here
        print(ChatHandler.clients)


class ChatServer(ForkingMixIn, UDPServer):
    pass


if __name__ == '__main__':
    server = ChatServer((host, port), ChatHandler)
    ChatHandler.clients = multiprocessing.Manager().list()
    server_process = multiprocessing.Process(target=server.serve_forever)
    server_process.daemon = False
    server_process.start()

如何解决这个问题?谢谢!

Output:

Exception happened during processing of request from ('127.0.0.1', 55679)
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/multiprocessing/managers.py", line 724, in _callmethod
    conn = self._tls.connection
AttributeError: 'ForkAwareLocal' object has no attribute 'connection'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/socketserver.py", line 584, in process_request
    self.finish_request(request, client_address)
  File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/socketserver.py", line 344, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/socketserver.py", line 665, in __init__
    self.handle()
  File "server.py", line 15, in handle
    ChatHandler.clients.append(self.client_address)
  File "<string>", line 2, in append
  File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/multiprocessing/managers.py", line 728, in _callmethod
    self._connect()
  File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/multiprocessing/managers.py", line 715, in _connect
    conn = self._Client(self._token.address, authkey=self._authkey)
  File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/multiprocessing/connection.py", line 495, in Client
    c = SocketClient(address)
  File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/multiprocessing/connection.py", line 624, in SocketClient
    s.connect(address)
FileNotFoundError: [Errno 2] No such file or directory

问题是你让主进程在启动工作进程后立即完成其执行。当创建的进程multiprocessing.Manager执行完毕后,Manager服务器被关闭,这意味着您的共享列表对象现在毫无用处。发生这种情况是因为Manager对象注册它的shutdown充当“终结器”multiprocessing模块,这意味着它将在进程退出之前运行。这是注册它的代码,在BaseManager.__init__:

    # register a finalizer
    self._state.value = State.STARTED
    self.shutdown = util.Finalize(
        self, type(self)._finalize_manager,
        args=(self._process, self._address, self._authkey,
              self._state, self._Client),
        exitpriority=0
        )

这是实际关闭的代码:

@staticmethod
def _finalize_manager(process, address, authkey, state, _Client):
    '''
    Shutdown the manager process; will be registered as a finalizer
    '''
    if process.is_alive():
        util.info('sending shutdown message to manager')
        try:
            conn = _Client(address, authkey=authkey)
            try:
                dispatch(conn, None, 'shutdown')
            finally:
                conn.close()
        except Exception:
            pass

        process.join(timeout=1.0)
        if process.is_alive():
            util.info('manager still alive')
            if hasattr(process, 'terminate'):
                util.info('trying to `terminate()` manager process')
                process.terminate()
                process.join(timeout=0.1)
                if process.is_alive():
                    util.info('manager still alive after terminate')

    state.value = State.SHUTDOWN
    try:
        del BaseProxy._address_to_local[address]
    except KeyError:
        pass

修复方法很简单 - 在启动运行 UDP 服务器的进程时,不要让主进程立即完成,方法是调用server_process.join():

import multiprocessing
from socketserver import UDPServer, ForkingMixIn, DatagramRequestHandler
from socket import socket, AF_INET, SOCK_DGRAM
from settings import host, port, number_of_connections

class ChatHandler(DatagramRequestHandler):

    def handle(self):
        cur_process = multiprocessing.current_process()
        data = self.request[0].strip()
        socket = self.request[1]
        ChatHandler.clients.append(self.client_address) # error here
        print(ChatHandler.clients)


class ChatServer(ForkingMixIn, UDPServer):
    pass


if __name__ == '__main__':
    server = ChatServer((host, port), ChatHandler)
    ChatHandler.clients = multiprocessing.Manager().list()
    server_process = multiprocessing.Process(target=server.serve_forever)
    server_process.daemon = False
    server_process.start()
    server_process.join() # This fixes the issue.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python服务器中进程之间共享列表 的相关文章

随机推荐

  • 避免 Firebase 可调用函数的 CORS 预检

    我有一个Firebase 可调用云函数 https firebase google com docs functions callable我在浏览器中的 javascript 应用程序中调用它 由于请求主机是 cloudfunctions
  • Spring自动装配参数化集合

    大家好 感谢您提前的帮助 我遇到一个问题 Spring 无法自动装配 ArrayBlockingQueue 类型的参数化成员变量 这是java代码 Controller public class SomeController Autowir
  • WPF 使用凭据启动浏览器

    我正在使用 WPF 和 C 我希望能够启动一个浏览器窗口 最有可能是 IE 并提供已知的凭据 以便基于 Windows 的应用程序可以处理从自身到外部浏览器的转换 而无需用户再次输入他 她的凭据 我确实知道如何启动浏览器 System Di
  • 仅在模块中加载 Yii Bootstrap

    我尝试仅在管理模块中加载 Yii Bootstrap 扩展 但它不起作用 我假设我需要预加载它或以某种方式启动它 谢谢 class AdminModule extends CWebModule public function init im
  • UIWebView 不断尝试加载但没有结果

    我正在尝试使用 UIWebView 连接到 wikiTravel 页面 这是我的代码 NSURL url NSURL URLWithString http wikitravel org en Beijing NSURLRequest req
  • 从命令行运行 Jupyter Notebook (.ipynb),就像它是 .py 文件一样

    我正在本地计算机上编写 Jupyter 笔记本 该笔记本最终将在远程服务器 运行 Ubuntu 上运行 每次我需要进行更改时 我都必须将笔记本导出为 py文件 然后从服务器的命令行调用它 我希望能够即时运行它 调用一个命令来获取当前的 ip
  • Gmail 的操作邮件程序配置

    我正在尝试将使用 Gmail SMTP 的电子邮件传送添加到我的应用程序中 我之前已经完成了 不太安全的应用程序 方式 但我不想在这个项目中使用此选项 我试图查看谷歌的文档或一些宝石以使其工作 但无济于事 每个人都只是发送一些代码 如下所示
  • 使背景图像与屏幕大小相同

    我希望背景图像填满屏幕 并且不担心失去宽高比 已经证实了一切 不要认为我错过了任何明显的事情 HTML phone margin auto height 737px width 654px background image url imgs
  • 比较sql server中两个字符串中的数字

    我有两个字符串作为 CountryLocationIDs 和 LocationIDs 其值 CountryLocationIDs 400 600 150 850 160 250 LocationIDs1 600 150 900 然后我需要另
  • 如何为特定用户选择最后一行?

    我有一个这样的表 requests id id user unix time 1 2353 1339412843 2 2353 1339412864 3 5462 1339412894 4 3422 1339412899 5 3422 13
  • 我的 Rails 路由应该是什么样子才能与 pushState Ember.js 路由一起使用?

    简而言之 当构建 Ember js 应用程序以持久保存到 Rails 应用程序时 我应该如何处理 Rails 路由 视图 我想我只需要 Rails 来渲染 application html erb 布局 以便 Ember js 应用程序初始
  • 如何修复 Chrome 扩展程序“未捕获的引用错误:文档未定义”错误? [复制]

    这个问题在这里已经有答案了 我正在创建一个扩展 我希望它能够在任何网站上找到特定的单词并突出显示它们 但是 在加载扩展程序后 我立即收到一条错误消息 有谁知道如何解决这一问题 我的代码如下 背景 js chrome runtime onIn
  • ffmpeg drawtext如何设置从右到左的方向

    i write arabic text to videos and it works fine but the issue is that the arabic language is written from right to left
  • 使用 MinMax 和 Alpha-Beta 剪枝找到最佳移动

    我正在为游戏开发 AI 我想使用MinMax算法与Alpha Beta 修剪 我对它的工作原理有一个粗略的了解 但我仍然无法从头开始编写代码 所以我花了两天的时间在网上寻找某种伪代码 我的问题是 我在网上找到的每个伪代码似乎都是基于寻找最佳
  • 属于主键?

    我有一个像这样的数据库布局 Users id name etc Lead id initials etc 基本上一个用户有很多线索 这initials字段映射到name用户表中的字段 我对用户设置有一个完美的关系 has many lead
  • 在编译时将多个文件中的变量收集到单个连续的内存块中

    我想在多个 c 文件中定义 并初始化 结构体的多个实例 但我希望它们在编译时收集到一个连续的数组中 我一直在研究使用自定义部分并使用该部分的开始和结束地址作为结构数组的开始和结束 但我还没有完全弄清楚细节 而且我不想编写自定义部分链接器脚本
  • vim:无法加载库 libpython

    我不让 vim 与 python 支持一起工作 我使用以下配置编译 vim 7 4 972 configure enable shared with features huge enable multibyte enable cscope
  • 如何使用 mediaelement.js 获取 HTML5 音频播放列表?

    我尝试在 mediaelement js 中搜索音频播放列表的示例 但我没有找到 mediaelement js 支持音频播放列表吗 如果是这样 请支持我的示例代码或链接 非常感谢 我设法获得了一个超级基本 阅读 hacky 的播放列表演示
  • WAMP服务器将MySQL切换为MariaDB

    如何在WAMP 3 1 0中将数据库从MySQL切换到MariaDB 我正在寻找它 但我找不到它 从您显示的图像来看 MySQL 和 MariaDB 似乎都已经在运行 注意 这有点占用内存 简单测试看看 MySQL 和 MariaDB 是否
  • python服务器中进程之间共享列表

    我有简单的UDP服务器 它适用于多重处理 我想创建一个列表 其中包含有关所有客户的信息 I use Manager 但我不明白 如何在列表中附加信息 我需要传输 Manager 的对象来处理 但是如何 我使用新属性的方法不起作用 impor