mirror of
https://github.com/LiteyukiStudio/LiteyukiBot.git
synced 2024-11-26 14:05:03 +08:00
📝 添加shared_memory文档
This commit is contained in:
parent
85a13251a5
commit
b356524a9e
@ -5,13 +5,15 @@ order: 4
|
||||
category: 开发
|
||||
---
|
||||
|
||||
## 简介
|
||||
## **通道通信**
|
||||
|
||||
### 简介
|
||||
|
||||
轻雪运行在主进程 MainProcess 里,其他插件框架进程是伴随的子进程,因此无法通过内存共享和直接对象传递的方式进行通信,轻雪提供了一个通道`Channel`用于跨进程通信,你可以通过`Channel`发送消息给其他进程,也可以监听其他进程的消息。
|
||||
|
||||
例如子进程接收到用户信息需要重启机器人,这时可以通过通道对主进程发送消息,主进程接收到消息后重启对应子进程。
|
||||
|
||||
## 快速开始
|
||||
### 快速开始
|
||||
|
||||
通道是全双工的,有两种接收模式,但一个通道只能使用一种,即被动模式和主动模式,被动模式由`chan.on_receive()`装饰回调函数实现,主动模式需调用`chan.receive()`实现
|
||||
|
||||
@ -78,3 +80,23 @@ async def on_startup():
|
||||
..-..-.. ..:..:.. [ℹ️信息] Active receive: I am liteyuki main process active
|
||||
...
|
||||
```
|
||||
|
||||
## **共享内存通信**
|
||||
|
||||
### 简介
|
||||
|
||||
- 相比于普通进程通信,内存共享使得代码编写更加简洁,轻雪框架提供了一个内存共享通信的接口,你可以通过`storage`模块实现内存共享通信
|
||||
- 内存共享是线程安全的,你可以在多个线程中读写共享内存,线程锁会自动保护共享内存的读写操作
|
||||
|
||||
### 快速开始
|
||||
|
||||
- 在任意进程中均可使用
|
||||
|
||||
```python
|
||||
from liteyuki.comm.storage import shared_memory
|
||||
|
||||
shared_memory.set("key", "value") # 设置共享内存
|
||||
value = shared_memory.get("key") # 获取共享内存
|
||||
```
|
||||
|
||||
- 源代码:[liteyuki/comm/storage.py](https://github.com/LiteyukiStudio/LiteyukiBot/blob/main/liteyuki/comm/storage.py)
|
24
docs/dev/dev_shared_memory.md
Normal file
24
docs/dev/dev_shared_memory.md
Normal file
@ -0,0 +1,24 @@
|
||||
---
|
||||
title: 内存共享通信
|
||||
icon: exchange-alt
|
||||
order: 5
|
||||
category: 开发
|
||||
---
|
||||
|
||||
# 简介
|
||||
|
||||
相比于普通进程通信,内存共享使得代码编写更加简洁,轻雪框架提供了一个内存共享通信的接口,你可以通过`shared_memory`模块实现内存共享通信
|
||||
内存共享是线程安全的,你可以在多个线程中读写共享内存,线程锁会自动保护共享内存的读写操作
|
||||
|
||||
## 快速开始
|
||||
|
||||
- 在任意进程中均可使用
|
||||
|
||||
```python
|
||||
from liteyuki.comm.storage import shared_memory
|
||||
|
||||
shared_memory.set("key", "value") # 设置共享内存
|
||||
value = shared_memory.get("key") # 获取共享内存
|
||||
```
|
||||
|
||||
- 源代码:[liteyuki/comm/storage.py](https://github.com/LiteyukiStudio/LiteyukiBot/blob/main/liteyuki/comm/storage.py)
|
@ -1,13 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved
|
||||
|
||||
@Time : 2024/7/26 下午10:36
|
||||
@Author : snowykami
|
||||
@Email : snowykami@outlook.com
|
||||
@File : __init__.py
|
||||
@Software: PyCharm
|
||||
该模块用于轻雪主进程和Nonebot子进程之间的通信
|
||||
依赖关系
|
||||
event -> _
|
||||
storage -> channel
|
||||
rpc -> channel, storage
|
||||
"""
|
||||
from liteyuki.comm.channel import (
|
||||
Channel,
|
||||
|
@ -136,8 +136,9 @@ class KeyValueStoreNoLock:
|
||||
if IS_MAIN_PROCESS:
|
||||
return self._store.get(key, default)
|
||||
else:
|
||||
self.passive_chan.send(("get", key, default))
|
||||
return self.active_chan.receive()
|
||||
temp_chan = Channel("temp_chan")
|
||||
self.passive_chan.send(("get", key, default, temp_chan))
|
||||
return temp_chan.receive()
|
||||
|
||||
def delete(self, key: str, ignore_key_error: bool = True) -> None:
|
||||
"""
|
||||
@ -169,8 +170,9 @@ class KeyValueStoreNoLock:
|
||||
if IS_MAIN_PROCESS:
|
||||
return self._store
|
||||
else:
|
||||
self.passive_chan.send(("get_all",))
|
||||
return self.active_chan.receive()
|
||||
temp_chan = Channel("temp_chan")
|
||||
self.passive_chan.send(("get_all", temp_chan))
|
||||
return temp_chan.receive()
|
||||
|
||||
|
||||
class GlobalKeyValueStore:
|
||||
@ -197,28 +199,29 @@ if IS_MAIN_PROCESS:
|
||||
|
||||
|
||||
@shared_memory.passive_chan.on_receive(lambda d: d[0] == "get")
|
||||
def on_get(d):
|
||||
shared_memory.active_chan.send(shared_memory.get(d[1], d[2]))
|
||||
def on_get(data: tuple[str, str, any, Channel]):
|
||||
data[3].send(shared_memory.get(data[1], data[2]))
|
||||
|
||||
|
||||
@shared_memory.passive_chan.on_receive(lambda d: d[0] == "set")
|
||||
def on_set(d):
|
||||
shared_memory.set(d[1], d[2])
|
||||
def on_set(data: tuple[str, str, any]):
|
||||
shared_memory.set(data[1], data[2])
|
||||
|
||||
|
||||
@shared_memory.passive_chan.on_receive(lambda d: d[0] == "delete")
|
||||
def on_delete(d):
|
||||
shared_memory.delete(d[1])
|
||||
def on_delete(data: tuple[str, str]):
|
||||
shared_memory.delete(data[1])
|
||||
|
||||
|
||||
@shared_memory.passive_chan.on_receive(lambda d: d[0] == "get_all")
|
||||
def on_get_all(d):
|
||||
if d[0] == "get_all":
|
||||
shared_memory.active_chan.send(shared_memory.get_all())
|
||||
def on_get_all(data: tuple[str, Channel]):
|
||||
if data[0] == "get_all":
|
||||
data[1].send(shared_memory.get_all())
|
||||
else:
|
||||
# 子进程在入口函数中对shared_memory进行初始化
|
||||
shared_memory = None
|
||||
|
||||
_ref_count = 0 # 引用计数
|
||||
_ref_count = 0 # import 引用计数, 防止获取空指针
|
||||
if not IS_MAIN_PROCESS:
|
||||
if (shared_memory is None) and _ref_count > 1:
|
||||
raise RuntimeError("Shared memory not initialized.")
|
||||
|
@ -1,6 +1,5 @@
|
||||
import threading
|
||||
|
||||
from nonebot import logger
|
||||
from liteyuki.comm.channel import active_channel
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user