add old lci module
This commit is contained in:
1 parent
38a6e815f0
commit
8499631091
171 files changed
+25562
No files matched your search
@@ -0,0 +1,29 @@
|
||||
.git/
|
||||
.vscode/
|
||||
.idea/
|
||||
.cache/
|
||||
|
||||
#
|
||||
init.csv
|
||||
|
||||
|
||||
# cangjie
|
||||
build/
|
||||
target/
|
||||
output/
|
||||
module-resolve.json
|
||||
module-lock.json
|
||||
cjpm.lock
|
||||
.cjpm-history
|
||||
*.macrocall
|
||||
*.gcda
|
||||
*.gcno
|
||||
|
||||
|
||||
# 其他
|
||||
log
|
||||
report
|
||||
tmp
|
||||
|
||||
# ide
|
||||
.arts
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) [year] [fullname]
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
## 为什么要做一个这样的项目
|
||||
|
||||
当时想做一个树莓派机器人,是准备用python来写控制程序,可是当时python的多线程能力较弱,
|
||||
|
||||
所以想到使用子系统,可是我没有VPN,无法安装ROS,所以就自己写了一个进程托管程序
|
||||
|
||||
## 使用方式
|
||||
|
||||
### 启动列表
|
||||
```bash
|
||||
# 创建启动列表,每一行是一个进程
|
||||
touch init.csv
|
||||
```
|
||||
|
||||
### 创建进程
|
||||
```bash
|
||||
curl -X POST http://localhost:5200/api/v2/create -d '["ls"]
|
||||
```
|
||||
|
||||
### 进程列表
|
||||
```bash
|
||||
curl http://localhost:5200/api/v2/list
|
||||
```
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
cd "$(dirname "$0")" || exit
|
||||
#source ./.env/bin/activate
|
||||
source /cangjie/envsetup.sh
|
||||
exec cjpm run
|
||||
@@ -0,0 +1,24 @@
|
||||
[package]
|
||||
cjc-version = "1.0.0"
|
||||
name = "phs"
|
||||
description = "nothing here"
|
||||
version = "1.0.0"
|
||||
target-dir = ""
|
||||
src-dir = ""
|
||||
output-type = "executable"
|
||||
compile-option = ""
|
||||
override-compile-option = ""
|
||||
link-option = ""
|
||||
package-configuration = {}
|
||||
|
||||
[dependencies]
|
||||
[target.x86_64-unknown-linux-gnu]
|
||||
[target.x86_64-unknown-linux-gnu.bin-dependencies]
|
||||
path-option = ["/stdx/linux_x86_64_llvm/static/stdx"]
|
||||
[target.aarch64-unknown-linux-gnu]
|
||||
[target.aarch64-unknown-linux-gnu.bin-dependencies]
|
||||
path-option = ["/stdx/linux_aarch64_llvm/static/stdx"]
|
||||
[target.x86_64-w64-mingw32] # 系统架构和 OS 信息
|
||||
[target.x86_64-w64-mingw32.bin-dependencies]
|
||||
path-option = ["C:\\stdx\\windows_x86_64_llvm\\dynamic\\stdx"] # stdx 路径根据实际情况配置
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
[Unit]
|
||||
Description=TxL.phs
|
||||
After=network.target
|
||||
Wants=network.target
|
||||
|
||||
[Service]
|
||||
User=root
|
||||
Group=root
|
||||
WorkingDirectory=/root/___TxL/TestSuits/phs
|
||||
ExecStart=bash /root/___TxL/TestSuits/phs/_run.sh
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
StandardOutput=syslog
|
||||
StandardError=syslog
|
||||
SyslogIdentifier=mozart-python-host
|
||||
Environment=PYTHONUNBUFFERED=1
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,312 @@
|
||||
package phs
|
||||
import std.sync.*;
|
||||
|
||||
/*
|
||||
* Status 状态
|
||||
*
|
||||
* FIXME: 在枚举中定义操作函数
|
||||
*/
|
||||
enum Stat {
|
||||
SHUT | STOP | START | RUNNING
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Finite Status Machine 有限状态机
|
||||
*
|
||||
*
|
||||
* FIXME(TritiumQin): 1. 柯里化
|
||||
*
|
||||
* FIXME(qing): 支持自定义状态
|
||||
*/
|
||||
open class Fsm {
|
||||
|
||||
|
||||
/* 状态枚举 */
|
||||
private var stat: Stat = STOP
|
||||
|
||||
/* 线程安全 */
|
||||
private let mtx: Mutex = Mutex()
|
||||
|
||||
/*
|
||||
* 条件变量
|
||||
*
|
||||
* FIXME: 我不知道这么写意义何在
|
||||
*/
|
||||
private let condition: Condition = synchronized(mtx) {
|
||||
mtx.condition()
|
||||
}
|
||||
|
||||
/* 辅助条件变量的布尔标志 */
|
||||
private var flag: Bool = true
|
||||
|
||||
|
||||
/* ---------------------------------------------- */
|
||||
|
||||
/*
|
||||
* 阻塞等待状态改变,可以传入一个谓词,以确定什么时候终止
|
||||
*
|
||||
* 在该回调函数中返回true,则等待不会停止
|
||||
*/
|
||||
public func wait(keep!: (Stat) -> Bool = {_ => false}) {
|
||||
synchronized(mtx) {
|
||||
flag = true
|
||||
while(flag || keep(stat)) {
|
||||
condition.wait()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------- */
|
||||
|
||||
/*
|
||||
* 对状态机进行某种操作,输入一个谓词。
|
||||
*
|
||||
* 会激活堵塞线程
|
||||
*/
|
||||
public func doc(p: (Stat) -> Stat): Stat {
|
||||
synchronized(mtx) {
|
||||
stat = p(stat)
|
||||
flag= false // 试图唤醒阻塞的线程
|
||||
condition.notifyAll()
|
||||
return stat
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 对状态机进行某种操作,输入一个谓词。
|
||||
*
|
||||
* 不会激活堵塞线程
|
||||
*/
|
||||
public func dop(p: (Stat) -> Stat): Stat {
|
||||
synchronized(mtx) {
|
||||
stat = p(stat)
|
||||
return stat
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Controllable Thread 可控制线程
|
||||
*
|
||||
* FIXME(花间岛):
|
||||
* 1. 使用async语法糖
|
||||
* 2. 封装iocp
|
||||
*/
|
||||
open class Th {
|
||||
|
||||
/* 持有线程类型 */
|
||||
private var fut: Option<Future<Int64>> = None
|
||||
|
||||
/* 持有状态机类型 */
|
||||
private let fsm: Fsm = Fsm()
|
||||
|
||||
/*----------------------------------------------*/
|
||||
|
||||
/* 持有静止事件回调 */
|
||||
private var StopEvent: Option<() -> Unit> = None
|
||||
|
||||
/* 持有唤醒事件回调 */
|
||||
private var WakeEvent: Option<() -> Unit> = None
|
||||
|
||||
/* 持有循环事件回调 */
|
||||
private var LoopEvent: Option<() -> Unit> = None
|
||||
|
||||
/* 持有清理事件回调 */
|
||||
private var ClearEvent: Option<() -> Unit> = None
|
||||
|
||||
/* 持有线程主函数回调 */
|
||||
private var Main: Option<() -> Int64> = None // 线程主函数
|
||||
|
||||
/*----------------------------------------------*/
|
||||
|
||||
/* 使用谓词检查线程状态 */
|
||||
public func chkp(): Stat {
|
||||
return fsm.dop({ stat => return stat })
|
||||
}
|
||||
|
||||
/*----------------------------------------------*/
|
||||
|
||||
/* 进入关闭状态 */
|
||||
public func shut() {
|
||||
fsm.doc({ _ => return SHUT })
|
||||
}
|
||||
|
||||
/* 进入静止态 */
|
||||
public func stop() {
|
||||
fsm.doc({ _ => return STOP })
|
||||
}
|
||||
|
||||
/* 进入启动状态 */
|
||||
public func start() {
|
||||
fsm.doc({ _ => return START })
|
||||
}
|
||||
|
||||
/* 进入运行态 */
|
||||
public func run() {
|
||||
fsm.doc({ _ => return RUNNING })
|
||||
}
|
||||
|
||||
/*----------------------------------------------*/
|
||||
|
||||
/* 状态机是否处于静止态 */
|
||||
public func isStop() {
|
||||
return match( chkp() ) {
|
||||
case STOP => true
|
||||
case _ => false
|
||||
}}
|
||||
|
||||
/* 状态机是否处于关闭态 */
|
||||
public func isShut() {
|
||||
return match( chkp() ) {
|
||||
case SHUT => true
|
||||
case _ => false
|
||||
}}
|
||||
|
||||
/* 状态机是否处于开始状态 */
|
||||
public func isStart() {
|
||||
return match( chkp() ) {
|
||||
case START => true
|
||||
case _ => false
|
||||
}}
|
||||
|
||||
/* 状态机是否处于运行态 */
|
||||
public func isRunning() {
|
||||
return match( chkp() ) {
|
||||
case RUNNING => true
|
||||
case _ => false
|
||||
}}
|
||||
|
||||
/*----------------------------------------------*/
|
||||
|
||||
/* 扮演函数,即设置线程事件 */
|
||||
public func Act(
|
||||
|
||||
/* 静止事件 */
|
||||
stop!: Option<() -> Unit> = None,
|
||||
|
||||
/* 唤醒事件 */
|
||||
wake!: Option<() -> Unit> = None,
|
||||
|
||||
/* 循环事件 */
|
||||
loop!: Option<() -> Unit> = None,
|
||||
|
||||
/* 清理事件 */
|
||||
clear!:Option<() -> Unit> = None,
|
||||
|
||||
|
||||
/* 线程主函数 */
|
||||
mainloop!: Option<() -> Int64>= None
|
||||
|
||||
)
|
||||
|
||||
{
|
||||
|
||||
/* 只有静止态才能进行设置 */
|
||||
if (!isStop()) { return; }
|
||||
|
||||
/* ------------------------------------------------- */
|
||||
|
||||
/* 设置静止事件,确保退出了静止态 */
|
||||
StopEvent = stop ?? {=> fsm.wait(keep: {stat =>
|
||||
match(stat) {
|
||||
case STOP => true /* 保持等待 */
|
||||
case _ => false
|
||||
}
|
||||
})}
|
||||
|
||||
/* 唤醒事件,默认直接进入运行态 */
|
||||
WakeEvent = wake ?? {=> this.run()}
|
||||
|
||||
/* 循环事件,默认进行延时 */
|
||||
LoopEvent = loop ?? {=> sleep(100 * Duration.millisecond)}
|
||||
|
||||
/* 清理事件,默认什么都不做 */
|
||||
ClearEvent= clear?? {=> ;}
|
||||
|
||||
/* ------------------------------------------------- */
|
||||
|
||||
/* 线程主函数 */
|
||||
Main = mainloop ?? {=>
|
||||
|
||||
/* 回字形循环 外层 */
|
||||
while (!isShut()) {
|
||||
this.inner()
|
||||
}
|
||||
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
/* ------------------------------------------------- */
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* ------------- 回字形循环 内层 -------------- */
|
||||
|
||||
private func inner() {
|
||||
|
||||
/* 静止状态 */
|
||||
while(isStop()) { StopEvent.getOrThrow()() }
|
||||
|
||||
/* 唤醒事件 */
|
||||
if (isStart()) { WakeEvent.getOrThrow()() }
|
||||
|
||||
/* 运行状态 */
|
||||
while(isRunning()) { LoopEvent.getOrThrow()() }
|
||||
|
||||
/* 清理事件 */
|
||||
ClearEvent.getOrThrow()()
|
||||
|
||||
}
|
||||
|
||||
/* --------------------------------------------- */
|
||||
|
||||
/*
|
||||
* 创建资源,可控线程苏醒
|
||||
*
|
||||
* 如果在调用中等待线程启动,可能会造成死锁
|
||||
* 想了想觉得也没有这个必要
|
||||
*/
|
||||
public func wake() {
|
||||
|
||||
|
||||
/* 存在微小的冲突可能,所以我不让它进入静止态 */
|
||||
this.start()
|
||||
|
||||
|
||||
/* 创建卵 */
|
||||
fut = Some<Future<Int64>>(spawn {
|
||||
Main.getOrThrow()()
|
||||
})
|
||||
|
||||
|
||||
/* 等启动
|
||||
*
|
||||
* 20251020(qing): 如果线程启动太快,该等待可能会导致死锁
|
||||
*/
|
||||
//fsm.wait(keep: {stat => match(stat) {
|
||||
// case START => true
|
||||
// case _ => false
|
||||
//}})
|
||||
}
|
||||
|
||||
/* 等待线程结束 */
|
||||
public func wait() {
|
||||
let f = fut.getOrThrow()
|
||||
return f.get()
|
||||
}
|
||||
|
||||
/*
|
||||
* 关闭线程,然后等待线程结束
|
||||
*/
|
||||
public func shut_and_wait() {
|
||||
shut()
|
||||
wait()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
package phs
|
||||
|
||||
import std.io.*;
|
||||
import std.fs.*;
|
||||
import std.collection.*;
|
||||
import std.sync.*;
|
||||
import std.process.*;
|
||||
import stdx.net.http.*;
|
||||
import stdx.encoding.json.*;
|
||||
|
||||
const ADDR = "127.0.0.1" /* 监听IP地址 */
|
||||
const PORT = 5200u16 /* 端口 UInt16类型 */
|
||||
|
||||
|
||||
class Ps {
|
||||
private let ps = LinkedList<SubProcess>()
|
||||
private let mtx = Mutex()
|
||||
|
||||
/* 创建进程 */
|
||||
public func create(arr: Array<String>) {
|
||||
let path = arr[0]
|
||||
let args = arr[1..]
|
||||
let subp: SubProcess = launch(path, args,
|
||||
//stdIn: ProcessRedirect.Discard, /* WINDOWS中不支持输入重定向 */
|
||||
//stdOut: ProcessRedirect.Discard, /* 加了这行之后就在控制台看不到输出了 */
|
||||
//stdErr: ProcessRedirect.Discard
|
||||
)
|
||||
this.clear() /* 清理进程 */
|
||||
synchronized(mtx) {
|
||||
ps.addLast(subp)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* 返回进程列表 */
|
||||
public func list() {
|
||||
var msg = ""
|
||||
println('1')
|
||||
this.clear() /* 清理进程,有锁 */
|
||||
println('2')
|
||||
synchronized(mtx) {
|
||||
println('3')
|
||||
for (p in ps) {
|
||||
if (msg != "") { msg += "\n"; }
|
||||
msg += '${p.pid.toString()}\t'
|
||||
msg += '${p.command} '
|
||||
//for (i in p.arguments) { /* 加上这个会失败 */
|
||||
// msg += '${i} '
|
||||
//}
|
||||
/* 启动时间 */
|
||||
msg += '\t${p.userTime.toString()}'
|
||||
}
|
||||
println('4')
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
/* 杀死已经存在的进程 */
|
||||
public func kill(pid: Int64) {
|
||||
this.clear() /* 清理 */
|
||||
synchronized(mtx) {
|
||||
for (p in ps) {
|
||||
if (p.pid == pid) {
|
||||
p.terminate(force: true)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 进程自启动
|
||||
*
|
||||
* FIXME: 支持注释
|
||||
*/
|
||||
public func autoRun(csvpath: String) {
|
||||
let file = File(csvpath, Read)
|
||||
let bytes = readToEnd(file)
|
||||
let ctt = String.fromUtf8(bytes)
|
||||
let cmds = ctt.split("\n", removeEmpty: true)
|
||||
for (cmd in cmds) {
|
||||
try{
|
||||
let arr = cmd.split(" ", removeEmpty: true)
|
||||
this.create(arr)
|
||||
} catch (exp: Exception) {
|
||||
;
|
||||
}
|
||||
}
|
||||
file.close()
|
||||
}
|
||||
|
||||
/* 清理已经死去的进程,默认不加锁 */
|
||||
private func clear() {
|
||||
synchronized(mtx) {
|
||||
let len = ps.size
|
||||
for (i in (len-1)..=0 : -1) {
|
||||
try {
|
||||
let p = ps.nodeAt(i).getOrThrow()
|
||||
println("start...")
|
||||
p.value.wait(timeout: 1 * Duration.millisecond) /* 进程有没有退出 */
|
||||
println("end...")
|
||||
ps.remove(p)
|
||||
}
|
||||
catch (exp: TimeoutException) { /* 如果进程没有结束,会运行到这里 */
|
||||
;
|
||||
println("skip...")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 将JSON数组转为字符串的数组
|
||||
*
|
||||
* Json对象的每个元素只能是字符串,否则会报错
|
||||
*/
|
||||
func Jarr_to_arr(arr: JsonArray): Array<String> {
|
||||
let len = arr.size() // Json数组的长度
|
||||
let ret = Array<String>(len, repeat: "")
|
||||
for (i in 0..len) {
|
||||
let option: Option<JsonValue> = arr.get(i)
|
||||
let jitem: JsonValue = option.getOrThrow()
|
||||
let jstr: JsonString = jitem.asString()
|
||||
let str: String = jstr.getValue()
|
||||
ret[i] = str
|
||||
}
|
||||
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
/* cj命令行参数不包含可执行文件名 */
|
||||
main(_: Array<String>): Int64 {
|
||||
|
||||
/* 进程组 */
|
||||
let ps = Ps()
|
||||
ps.autoRun("./init.csv")
|
||||
|
||||
|
||||
/* 创建http服务器 */
|
||||
let server: Server = ServerBuilder()
|
||||
.addr(ADDR) /* 设置地址 */
|
||||
.port(PORT) /* 设置端口 */
|
||||
.build()
|
||||
|
||||
/* 创建进程的HTTP方法 */
|
||||
server.distributor.register("/api/v2/create", { context =>
|
||||
if (context.request.method == "POST") {
|
||||
let content = StringReader(context.request.body).readToEnd() /* 阅读请求体 */
|
||||
let array = JsonValue.fromStr(content).asArray() /* 解析json格式的请求体 */
|
||||
let net_args: Array<String> = Jarr_to_arr(array) /* json数组转原生数组 */
|
||||
ps.create(net_args)
|
||||
|
||||
/* ---- 准备响应 ---- */
|
||||
let Headers = HttpHeaders()
|
||||
Headers.add("Content-Type", "text/html; charset=utf-8;")
|
||||
context.responseBuilder.setHeaders(Headers)
|
||||
context.responseBuilder.body('OK')
|
||||
}
|
||||
})
|
||||
|
||||
/*
|
||||
* 输出进程列表的HTTP方法
|
||||
*/
|
||||
server.distributor.register("/api/v2/list", { context =>
|
||||
if (context.request.method == "GET") {
|
||||
|
||||
println('a')
|
||||
/* 准备表单字符串 */
|
||||
let ret = ps.list()
|
||||
|
||||
println('b')
|
||||
/**** 准备响应 ****/
|
||||
let Headers = HttpHeaders()
|
||||
Headers.add("Content-Type", "text/html; charset=utf-8;")
|
||||
context.responseBuilder.setHeaders(Headers)
|
||||
context.responseBuilder.body(ret)
|
||||
|
||||
println('c')
|
||||
}
|
||||
})
|
||||
|
||||
/* 杀死一个已经存在的进程 */
|
||||
server.distributor.register("/api/v2/kill", { context =>
|
||||
if (context.request.method == "POST") {
|
||||
let content = StringReader(context.request.body).readToEnd() /* 阅读请求体 */
|
||||
let target_pid = JsonValue.fromStr(content)
|
||||
.asObject()
|
||||
.get("pid")
|
||||
.getOrThrow()
|
||||
.asInt()
|
||||
.getValue()
|
||||
ps.kill(target_pid)
|
||||
|
||||
/**** 准备响应 ****/
|
||||
let Headers = HttpHeaders()
|
||||
Headers.add("Content-Type", "text/html; charset=utf-8;")
|
||||
context.responseBuilder.setHeaders(Headers)
|
||||
context.responseBuilder.body("done")
|
||||
}
|
||||
})
|
||||
|
||||
/* 服务器开始运行 */
|
||||
server.serve()
|
||||
return 0
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
import requests
|
||||
import json
|
||||
|
||||
|
||||
def create_process(cmd_list, url="http://localhost:5200/api/v2/create"):
|
||||
"""创建任意进程
|
||||
|
||||
Args:
|
||||
cmd_list (list): 命令和参数列表,例如 ["timeout", "/t", "1000"]
|
||||
url (str, optional): 请求URL,默认为 "http://localhost:5200/api/v2/create"
|
||||
|
||||
Returns:
|
||||
requests.Response: 响应对象
|
||||
"""
|
||||
try:
|
||||
# 发送POST请求
|
||||
response = requests.post(url, data=json.dumps(cmd_list), timeout=30)
|
||||
|
||||
# 返回响应对象供进一步处理
|
||||
return response
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"创建进程失败: {e}")
|
||||
return None
|
||||
|
||||
|
||||
def create_process_with_output(cmd_list, url="http://localhost:5200/api/v2/create"):
|
||||
"""创建任意进程并打印输出
|
||||
|
||||
Args:
|
||||
cmd_list (list): 命令和参数列表,例如 ["timeout", "/t", "1000"]
|
||||
url (str, optional): 请求URL,默认为 "http://localhost:5200/api/v2/create"
|
||||
|
||||
Returns:
|
||||
dict or str: 响应内容,JSON解析后的字典或原始文本
|
||||
"""
|
||||
response = create_process(cmd_list, url)
|
||||
|
||||
if response is None:
|
||||
return None
|
||||
|
||||
# 打印响应状态码
|
||||
print(f"响应状态码: {response.status_code}")
|
||||
|
||||
# 尝试解析响应内容为JSON格式并打印
|
||||
try:
|
||||
response_json = response.json()
|
||||
print(f"响应内容: {json.dumps(response_json, indent=2, ensure_ascii=False)}")
|
||||
return response_json
|
||||
except json.JSONDecodeError:
|
||||
print(f"响应内容(非JSON格式): {response.text}")
|
||||
return response.text
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 示例用法
|
||||
# 创建一个timeout进程,延迟1000毫秒
|
||||
cmd = ["timeout", "/t", "1000"]
|
||||
|
||||
# 使用默认URL
|
||||
print("使用默认URL:")
|
||||
create_process_with_output(cmd)
|
||||
|
||||
# 示例:使用自定义URL(注释掉,可根据需要取消注释)
|
||||
# print("\n使用自定义URL:")
|
||||
# custom_url = "http://localhost:5200/api/v2/create"
|
||||
# create_process_with_output(cmd, custom_url)
|
||||
@@ -0,0 +1,30 @@
|
||||
import requests
|
||||
import json
|
||||
|
||||
def test_create_process():
|
||||
"""测试访问phs web服务的create接口"""
|
||||
# 设置请求URL
|
||||
url = "http://localhost:5200/api/v2/create"
|
||||
|
||||
# 设置请求数据
|
||||
data = ["timeout", "/t", "1000"]
|
||||
|
||||
# 发送POST请求
|
||||
response = requests.post(url, data=json.dumps(data))
|
||||
|
||||
# 打印响应状态码
|
||||
print(f"响应状态码: {response.status_code}")
|
||||
|
||||
# 尝试解析响应内容为JSON格式并打印
|
||||
try:
|
||||
response_json = response.json()
|
||||
print(f"响应内容: {json.dumps(response_json, indent=2, ensure_ascii=False)}")
|
||||
except json.JSONDecodeError:
|
||||
print(f"响应内容(非JSON格式): {response.text}")
|
||||
|
||||
# 返回响应对象供进一步处理
|
||||
return response
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 执行测试函数
|
||||
test_create_process()
|
||||
@@ -0,0 +1,44 @@
|
||||
import requests
|
||||
import json
|
||||
import argparse
|
||||
|
||||
|
||||
def test_kill_process(pid):
|
||||
"""测试访问phs web服务的kill接口"""
|
||||
# 设置请求URL
|
||||
url = "http://localhost:5200/api/v2/kill"
|
||||
|
||||
# 构造请求消息体
|
||||
payload = {
|
||||
"pid": pid
|
||||
}
|
||||
|
||||
# 发送POST请求
|
||||
response = requests.post(url, json=payload)
|
||||
|
||||
# 打印响应状态码
|
||||
print(f"响应状态码: {response.status_code}")
|
||||
|
||||
# 尝试解析响应内容为JSON格式并打印
|
||||
try:
|
||||
response_json = response.json()
|
||||
print(f"响应内容: {json.dumps(response_json, indent=2, ensure_ascii=False)}")
|
||||
except json.JSONDecodeError:
|
||||
print(f"响应内容(非JSON格式): {response.text}")
|
||||
|
||||
# 返回响应对象供进一步处理
|
||||
return response
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 创建命令行参数解析器
|
||||
parser = argparse.ArgumentParser(description="测试访问phs web服务的kill接口")
|
||||
|
||||
# 添加pid参数
|
||||
parser.add_argument("pid", type=int, help="要杀死的进程ID")
|
||||
|
||||
# 解析命令行参数
|
||||
args = parser.parse_args()
|
||||
|
||||
# 执行测试函数,传入命令行参数中的pid
|
||||
test_kill_process(args.pid)
|
||||
@@ -0,0 +1,27 @@
|
||||
import requests
|
||||
import json
|
||||
|
||||
def test_create_process():
|
||||
"""测试访问phs web服务的create接口"""
|
||||
# 设置请求URL
|
||||
url = "http://localhost:5200/api/v2/list"
|
||||
|
||||
# 发送POST请求
|
||||
response = requests.get(url)
|
||||
|
||||
# 打印响应状态码
|
||||
print(f"响应状态码: {response.status_code}")
|
||||
|
||||
# 尝试解析响应内容为JSON格式并打印
|
||||
try:
|
||||
response_json = response.json()
|
||||
print(f"响应内容: {json.dumps(response_json, indent=2, ensure_ascii=False)}")
|
||||
except json.JSONDecodeError:
|
||||
print(f"响应内容(非JSON格式): {response.text}")
|
||||
|
||||
# 返回响应对象供进一步处理
|
||||
return response
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 执行测试函数
|
||||
test_create_process()
|
||||
Reference in new issue
Block a user