Files
micro_servers/lci/include/lci/p_th.h
T
2026-08-02 21:21:03 +08:00

161 lines
3.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
#include "Area.h"
#include "CmdArea.h"
#include "CommonThread.h"
namespace qing {
namespace lci{
/* PrintThread 打印线程 */
class p_th: public CommonThread {
public:
/**
* 构造函数 传入要读取的控制台设备文件描述符,背景画布,以及命令行区域
*/
p_th(std::string name, int masterfd, Drawable *back, CmdArea *font)
: CommonThread(name) {
this->masterfd = masterfd;
this->back = back;
this->font = font;
}
/**
* 析构函数 关闭线程
*
* 我在可控制线程中主要遇到的问题便是线程的自主终止,
*
* 在 Python 中似乎是只能实现可控制线程的手动退出的,
*
* 我在想是不是在cpp中也做成那样。
*
*
* FIXME(20260108): 啥意思不懂
*/
~p_th(){
/* 使线程自主关闭 */
if (this->chk() != lci::SSHUT){
this->shut();
}
/* 等待线程退出 */
this->WaitClose();
}
/**
* 暂时删除复制构造函数,因为复制出一个与原来线程无关的空白线程似乎没有什么作用
*
* 如果让两个变量引用同一个线程,会使得它们在结束的时候出现错误。
*/
p_th(p_th&) = delete;
/**
* 线程睡眠阶段的操作函数,线程等待。
*
* suspend() 方法似乎不太稳定,我还得再测试测试。
*/
void StopEvent() override {
this->suspend();
}
/**
* 线程苏醒之后执行的操作,线程启动。
*
* 我不知道为什么要等待1秒。
*/
void WakeEvent() {
/* 将文件描述符集合清零 */
FD_ZERO(&read_fds);
/* 清空缓存字符串 */
output = "";
/* 设置完毕,线程进入运行态 */
this->run();
}
/**
* 线程运行阶段的循环体,线程运行。
*
* 使用 SELECT 进行缓冲区的探测。
*/
void LoopEvent() {
/* 对可读集合进行清零 */
//FD_ZERO(&read_fds);
/* 设置可读集合 */
//FD_SET(masterfd, &read_fds);
/**
* 仅在集合中不存在控制台描述符时,才往其中添加该描述符
*
* 在这个集合中,应该只会存在这一个文件描述符吧
*/
if (!FD_ISSET(masterfd, &read_fds))
FD_SET(masterfd, &read_fds);
/* 设置超时时间 */
timeout.tv_sec = 0;
timeout.tv_usec = 10000;
int ret = select(masterfd + 1, &read_fds, NULL, NULL, &timeout);
if (ret == -1) {
//throw std::runtime_error("select");
//this->stop();
return; /* qing(20260108): 为什么不停止 */
} else if (ret == 0) { /* No data to read 无值可读 */
if (output == "") return; /* 在空闲时进行打印*/
font->print((char*)output.c_str(), 0); /* 按次为单位进行刷新应该可以提高效率 20260108(qing): ?*/
back->flush(font, false);
output = "";
} else {
if (FD_ISSET(masterfd, &read_fds)) { /* 有值可读 */
nread = read(masterfd, buffer, sizeof(buffer));
if (nread > 0) {
buffer[nread] = '\0';
output += buffer;
}
}
}
}
/**
* 线程执行过后的清理函数,清理资源。
*
* 什么也不做。我们在唤醒时并未申请资源。
*/
void ClearEvent() {
;
}
private:
int masterfd; /* 对象中存储的要读取的控制台设备文件描述符。 */
Drawable *back; /* 对象中存储的背景画布指针 */
CmdArea *font; /* 对象中存储的命令行区域指针 */
std::string output; /* 从终端设备中读取的进程输出 */
//--------------------------------------------
/* 下面的变量是为了提高速度,避免重复申请 */
fd_set read_fds; /* 文件描述符集合,用于存储 SELECT 返回的可读区域 */
struct timeval timeout; /* 时间结构体 用于传入 SELECT 函数的超时时间 */
ssize_t nread; /* 这一次从控制台中所读取大小 */
char buffer[1024]; /* 存储从控制台中读取字符的缓冲区,一次最多读这么多 */
};
}
}