【Linux】命名管道的妙用:实现进程控制与实时字符交互

1. 进程池

在匿名管道学习后,我们已经实现了一个基于匿名管道的简单进程控制,现在我们学习了命名管道来试试用命名管道来实现进程控制吧。 正在匿名管道时,我们已经实现了进程的控制,命名管道只要在其基础上进行一些修改就可以了。

2. 进程池的功能2.1 可被执行的任务

进程池是为了实现对进程的控制,通过父进程对众多子进程的管理,实现高效的进程执行任务。 我们可以先虚构一些任务出来,后续的子进程就来执行这些任务:

打印日志将数据插入数据库请求网络 可以用这些任务可以写成单独的函数,然后用一个类来管理这些任务。 类的成员变量: 利用哈希表来存储这些任务 类的功能有:展示可执行的任务执行任务 具体的代码如下:代码语言:javascript代码运行次数:0运行复制

typedef void(*task_t)(void);/*函数指针*///任务集void printLog(){    std::cout<<"PID:"<<getpid()<<",正在打印日志..."<<std::endl;}void MySQLInsert(){    std::cout<<"PID"<<getpid()<<",正在将数据插入数据库..."<<std::endl;}void NetRequest(){    std::cout<<"PID"<<getpid()<<",正在请求网络..."<<std::endl;}class Task{private:    std::unordered_map st_;public:    Task()    {        st_ = {{"打印日志",printLog},{"插入数据",MySQLInsert},{"请求网络",NetRequest}};    }    void showTask()/*展示任务*/    {        std::cout<<"可选任务:"<<std::endl;        std::cout<<" {";        for(auto&s:st_)        {            std::cout<<s.first<<' ';        }        std::cout<<'}'<<std::endl;    }    void curTask(const std::string& t)/*执行任务*/    {        if(st_.find(t) == st_.end())        {            std::cout<<"没有这个任务哦~"<<std::endl;        }        else        {            st_[t]();/*调用任务*/        }    }};

2.2 进程控制(重点)

进程控制是进程池的重点、核心。我们实现进程池也就是为了执行对进程的控制。 如何控制进程呢?

创建进程展示空闲子进程子进程等待任务的发配父进程为子进程发配任务杀死/回收进程2.2.1 子进程类

为了实现这些功能,同样我们用一个类来封装它们。除此之外,还记得我们在实现基于匿名管道的进程控制吗?我们还需要一个类来描述子进程。因为我们需要知道父进程的每个写端的文件描述符和哪个子进程通过命名管道建立起来联系。 所以子进程类具有的属性就有了:

子进程的PID写端的文件描述符编号名字 其中第3和第4个属性是为了方便父进程管理而加入的,后续进程控制类需要用数组将各个子进程存储起来。 子进程类代码如下:代码语言:javascript代码运行次数:0运行复制

class SubProcesses{private:    pid_t id_;    int processNum_;    int wfd_;    std::string name_;    static int cnt_;public:    SubProcesses(pid_t id,int wfd)    :id_(id),processNum_(cnt_++),wfd_(wfd)    {        char buff[SIZE]{0};        snprintf(buff,SIZE,"Process %d | pid:wfd [%d:%d]",processNum_,id_,wfd_);        name_ = buff;    }    pid_t getId()    {        return id_;    }    std::string getName()    {        return name_;    }    int getWfd()    {        return wfd_;    }};int SubProcesses::cnt_ = 1;

2.2 进程控制

那么进程类会具有什么属性呢?我们需要将创建出子进程进行管理可以用一个

vecotr

来对其进行管理,还需要知道我们需要创建的子进程数量,因为是基于命名管道的进程控制,为此我们还必须对个个进程管道进行管理,同样用

vector

将它们装起来。除此之外在来个权限掩码也可以。 如此进程控制类的成员变量:

管理着子进程的

vector

类。管理着命名管道的

vector

类。记录需要创建的子进程数目。权限掩码。 下面开始实现函数:2.2.2 创建子进程

创建子进程,创建子进程同样还是用到

fork

函数,不同的是不在需要

pipe

函数来创建管道了。现在已经变成了

mkfifo

函数。 和匿名管道那一样,我们要记得关闭子进程的写端,尽管子进程并没有主动打开写端,但是因为子进程继承父进程的缘故,依然会吧父进程的写端给继承过了的。一点定是要关闭的。

代码语言:javascript代码运行次数:0运行复制

void createProcess(){std::vector vfd;/*关闭子进程的写端*/for(int i = 1;i<=subProcessNum_;++i){std::string fifoName = "fifo-"+std::to_string(i); int ret = mkfifo(fifoName.c_str(),mode_);/*创建命名管道*/if(ret == -1){perror("mkfifo");exit(1);}namePipe_.push_back(fifoName);/*存入命名管道*/pid_t id = fork();/*创建子进程*/if(id < 0){perror("fork");exit(1);}else if(id == 0){//子进程for(auto&fd:vfd){close(fd);}int rfd = open(fifoName.c_str(),O_RDONLY);if(rfd == -1){perror("open");exit(1);}//开始等待父进程的指令waitTask(rfd); /*子进程等待任务委派*/close(rfd);exit(0);}//父进程int wfd = open(fifoName.c_str(),O_WRONLY);if(wfd == -1){perror("open");exit(1);}subProcess_.push_back({id,wfd});/*存入子进程信息*/fifoName.push_back(wfd);}}

2.2.3 子进程等待任务

死循环等待任务,当写端关闭再退出。

代码语言:javascript代码运行次数:0运行复制

void waitTask(int rfd)/*子进程等待任务委派*/{while(true){char buff[SIZE];int n = read(rfd,buff,SIZE);if(n == -1){perror("read");exit(1);}else if(n>0){Task().curTask((std::string)buff);}else if(n == 0){/*证明写端没有写消息了*/std::cout<<"写端已经关闭,读端也即将关闭!"<<std::endl;break;}}}

2.2.4 展示空闲进程代码语言:javascript代码运行次数:0运行复制

/*展示可选进程*/    void showProcess()    {        std::cout<<"目前可用进程有:"<<std::endl;        int i = 0;        std::cout<<"|";        for(auto&x:subProcess_)        {            std::cout<<"进程编号:"<<(i++)<<"进程PID:"<<x.getId()<<"| ";        }    }

2.2.5 分配任务给子进程

该函数的功能就分配任务,由用户自己选择子进程来执行任务。

INFINITE ALBUM INFINITE ALBUM

面向游戏玩家的生成式AI音乐

INFINITE ALBUM 144 查看详情 INFINITE ALBUM 代码语言:javascript代码运行次数:0运行复制

/*下达任务给子进程*/void sendTask(){std::cout<<"------------------------"<<std::endl;while(true){int input = 0;do{showProcess();std::cout<>input;   }while(input=subProcessNum_);Task().showTask();std::string taskName;std::cout<>taskName;if(taskName == "exit"){break;}std::cout< "<<subProcess_[input].getName()<<" 执行"<<taskName<<" 任务"<<std::endl;write(subProcess_[input].getWfd(),taskName.c_str(),taskName.size());sleep(1);}}

2.2.6 回收子进程

回收子进程的同时也不能忘记关闭文件描述符和关闭命名管道

代码语言:javascript代码运行次数:0运行复制

/*关闭写端、删除文件、等待子进程退出*/    void waitProcess()    {        for(int i = 0;i<subProcessNum_;++i)        {            close(subProcess_[i].getWfd());            unlink(namePipe_[i].c_str());            waitpid(subProcess_[i].getId(),nullptr,0);        }        std::cout<<"所有子进程已回收!"<<std::endl;    }

代码代码语言:javascript代码运行次数:0运行复制

#include #include #include #include #include #include #include #include #include #include /** * 该文件为进程池的公共代码段 * 进程池为利用命名管道实现的,简称命名管道进程池 * 代码的主要功能包括:创建进程,控制进程实现委派给它的任务,等待进程 */#define SIZE 1024typedef void(*task_t)(void);//任务集void printLog(){    std::cout<<"PID:"<<getpid()<<",正在打印日志..."<<std::endl;}void MySQLInsert(){    std::cout<<"PID"<<getpid()<<",正在将数据插入数据库..."<<std::endl;}void NetRequest(){    std::cout<<"PID"<<getpid()<<",正在请求网络..."<<std::endl;}class Task{private:    std::unordered_map st_;public:    Task()    {        st_ = {{"打印日志",printLog},{"插入数据",MySQLInsert},{"请求网络",NetRequest}};    }    void showTask()/*展示任务*/    {        std::cout<<"可选任务:"<<std::endl;        std::cout<<" {";        for(auto&s:st_)        {            std::cout<<s.first<<' ';        }        std::cout<<'}'<<std::endl;    }    void curTask(const std::string& t)/*执行任务*/    {        if(st_.find(t) == st_.end())        {            std::cout<<"没有这个任务哦~"<<std::endl;        }        else        {            st_[t]();/*调用任务*/        }    }};class SubProcesses{private:    pid_t id_;    int processNum_;    int wfd_;    std::string name_;    static int cnt_;public:    SubProcesses(pid_t id,int wfd)    :id_(id),processNum_(cnt_++),wfd_(wfd)    {        char buff[SIZE]{0};        snprintf(buff,SIZE,"Process %d | pid:wfd [%d:%d]",processNum_,id_,wfd_);        name_ = buff;    }    pid_t getId()    {        return id_;    }    std::string getName()    {        return name_;    }    int getWfd()    {        return wfd_;    }};int SubProcesses::cnt_ = 1;class ProcessCtrl{private:    std::vector subProcess_;/*子进程信息表*/    std::vector namePipe_;/*命名管道信息表*/    int subProcessNum_ ;/*需要创建的子进程数目*/    mode_t mode_ ;public:    ProcessCtrl(int subProcessNum = 3,mode_t mode = 0666)    :subProcessNum_(subProcessNum),mode_(mode)    {createProcess();/*开始创建子进程*/}    void createProcess()    {        std::vector vfd;/*关闭子进程的写端*/        for(int i = 1;i<=subProcessNum_;++i)        {            std::string fifoName = "fifo-"+std::to_string(i);             int ret = mkfifo(fifoName.c_str(),mode_);/*创建命名管道*/            if(ret == -1)            {                perror("mkfifo");                exit(1);            }            namePipe_.push_back(fifoName);/*存入命名管道*/            pid_t id = fork();/*创建子进程*/            if(id 0)            {                Task().curTask((std::string)buff);            }            else if(n == 0)            {                /*证明写端没有写消息了*/                std::cout<<"写端已经关闭,读端也即将关闭!"<<std::endl;                break;            }        }            }    /*展示可选进程*/    void showProcess()    {        std::cout<<"目前可用进程有:"<<std::endl;        int i = 0;        std::cout<<"|";        for(auto&x:subProcess_)        {            std::cout<<"进程编号:"<<(i++)<<"进程PID:"<<x.getId()<<"| ";        }        std::cout<<std::endl;    }    /*下达任务给子进程*/    void sendTask()    {        std::cout<<"------------------------"<<std::endl;        while(true)        {            int input = 0;            do            {                showProcess();                std::cout<>input;               }while(input=subProcessNum_);            Task().showTask();            std::string taskName;            std::cout<>taskName;            if(taskName == "exit")            {                break;            }            std::cout< "<<subProcess_[input].getName()<<" 执行"<<taskName<<" 任务"<<std::endl;            write(subProcess_[input].getWfd(),taskName.c_str(),taskName.size());            sleep(1);        }    }    /*关闭写端、删除文件、等待子进程退出*/    void waitProcess()    {        for(int i = 0;i<subProcessNum_;++i)        {            close(subProcess_[i].getWfd());            unlink(namePipe_[i].c_str());            waitpid(subProcess_[i].getId(),nullptr,0);        }        std::cout<<"所有子进程已回收!"<<std::endl;    }};int main(){    ProcessCtrl pp;    pp.sendTask();    return 0;}

运行结果

【Linux】命名管道的妙用:实现进程控制与实时字符交互运行结果

3. 实时读取字符

我们还可以通过命名管道来实现字符的实时读取,还挺有意思的,为了实现这个功能,我们不仅需要会使用命名管道,还有如

system()和fflush()

函数。

3.1 公共区域代码语言:javascript代码运行次数:0运行复制

#include #include #include #include #include #include #include #include #define SIZE 1024//命名管道const char* namePipe = "./fifo";//权限掩码const mode_t mode = 0666;

3.2 客户端

客户端用来向服务端发送消息

代码语言:javascript代码运行次数:0运行复制

/** * 该文件为客户端,用来实时向服务端发送字符 */#include "common.hpp"int main(){    /**主要步骤:     * 1.创建命名管道     * 2.打开命名管道     * 3.写入字符到命名管道当中     * 4.关闭命名管道        * */    int mk = mkfifo(namePipe,mode);    if(mk == -1)    {        perror("mkfifo");        exit(1);    }    int fd = open(namePipe,O_WRONLY);//写方式打开    if(fd == -1)    {        perror("open");        exit(1);    }    std::cout<<"开始输入字符:ctrl+c退出"<<std::endl;    while(true)    {        system("stty raw");/*调用 shell 命令 `stty raw` 的,它的作用是将终端设置为 原始模式(raw mode)。*/        int c = getchar();        system("stty -raw");/*用于将终端从 原始模式(raw mode) 恢复到 规范模式(cooked mode)。*/        if(c == 3)/*ctrl+c == 3 */        {            std::cout<<"exit!"<=0);        (void)n;/*消除未使用警告*/    }    close(fd);    unlink(namePipe);    return 0;}

3.3 服务端代码语言:javascript代码运行次数:0运行复制

/** * 该文件为服务端,用来实时接受客户端输出的字符 */#include "common.hpp"int main(){    /**     * 实时读取客户端发来的字符     * 主要功能:     *      * 1.已读方式打开命名管道文件     * 2.利用fflush实时刷新缓冲区的字符     * 3.关闭文件描述符     */    int fd = open(namePipe,O_RDONLY);    assert(fd!=-1);    while(true)    {        char buff[SIZE]{0};        ssize_t n = read(fd,buff,SIZE-1);        if(n>0)        {            buff[n] = 0;            printf("%c",buff[0]);            fflush(stdout);        }        else if(n == 0)        {            std::cout<<std::endl;            std::cout<<"写端退出,终止读端"<<std::endl;            break;        }        else         {            perror("read");            close(fd);            exit(1);        }    }    close(fd);    return 0;}

效果图

屏幕录制 2024-11-20 202850

往期Linux文章:Linux专栏

4.总结

通过命名管道实现了这两个简单的小程序,其实这些小程序的本质都是一样的:创建命名管道 -> 打开命名管道 -> 通信 -> 关闭命名管道,掌握其中一个即可融会贯通! 感谢阅读。

以上就是【Linux】命名管道的妙用:实现进程控制与实时字符交互的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/796041.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
CentOS 6.5 下安装MySQL 5.7.12详细步骤(图文)
上一篇 2025年11月26日 16:04:53
如何导入js
下一篇 2025年11月26日 16:05:00

相关推荐

  • mysql储存过程中循环语句有哪些

    mysql储存过程中循环语句有哪些mysql储存过程中循环语句有哪些mysql储存过程中循环语句有哪些mysql储存过程中循环语句有哪些

    MySQL存储过程中提供WHILE和REPEAT两种循环语句:WHILE循环:根据条件重复执行代码块,条件为真时继续执行。REPEAT循环:先执行代码块,再检查条件是否为真,为假则再次执行代码块。 MySQL存储过程中的循环语句 MySQL存储过程中支持以下两种循环语句: WHILE 循环 WHIL…

    2026年9月24日 用户投稿
    000
  • sublime怎么配置js prettier自动格式化_Sublime集成Prettier实现JS代码自动格式化

    sublime怎么配置js prettier自动格式化_Sublime集成Prettier实现JS代码自动格式化sublime怎么配置js prettier自动格式化_Sublime集成Prettier实现JS代码自动格式化sublime怎么配置js prettier自动格式化_Sublime集成Prettier实现JS代码自动格式化sublime怎么配置js prettier自动格式化_Sublime集成Prettier实现JS代码自动格式化

    首先安装Node.js和Prettier,再通过Package Control安装JsPrettier插件,配置prettier_cli_path、node_path及auto_format_on_save为true,确保保存时自动格式化JS代码。 Sublime Text 虽然轻量,但通过插件可以…

    2026年9月24日 用户投稿
    700
  • Java中实现PDF文档并排对比及差异高亮显示:使用pdfcompare库

    Java中实现PDF文档并排对比及差异高亮显示:使用pdfcompare库Java中实现PDF文档并排对比及差异高亮显示:使用pdfcompare库Java中实现PDF文档并排对比及差异高亮显示:使用pdfcompare库Java中实现PDF文档并排对比及差异高亮显示:使用pdfcompare库

    本文介绍了如何在Java环境中,利用开源库pdfcompare实现两个PDF文档的并排对比,并独立高亮显示其差异。针对传统方案合并PDF的痛点,pdfcompare提供了一种优雅的解决方案,确保原始文档结构不变,仅在各自副本中标记出不同之处,满足特定业务需求。 1. 背景与挑战 在处理文档版本控制或…

    2026年9月24日 用户投稿
    1100
  • mysql存储过程保存在哪

    mysql存储过程保存在哪mysql存储过程保存在哪mysql存储过程保存在哪mysql存储过程保存在哪

    MySQL 存储过程保存在 mysql.proc 表中,该表存储了存储过程的所有信息,包括名称、定义、创建者和修改时间。 MySQL 存储过程保存在哪里? MySQL 中的存储过程保存在数据库的 mysql.proc 表中。这个表存储了所有在数据库中创建的存储过程的信息。 表结构 mysql.pro…

    2026年9月24日 用户投稿
    1700
  • Java 正则表达式非贪婪匹配替换:精准替换字符串中的特定部分

    Java 正则表达式非贪婪匹配替换:精准替换字符串中的特定部分Java 正则表达式非贪婪匹配替换:精准替换字符串中的特定部分Java 正则表达式非贪婪匹配替换:精准替换字符串中的特定部分Java 正则表达式非贪婪匹配替换:精准替换字符串中的特定部分

    本文旨在解决 Java 中使用正则表达式进行字符串替换时,如何避免过度匹配,实现对特定字符串的精准替换。通过使用单词边界 ,我们可以确保只替换独立的 $c 字符串,而不会影响到 $c_new 等包含 $c 的其他字符串。本文将提供详细的代码示例和解释,帮助开发者掌握这一技巧。 在 Java 中,使用…

    2026年9月24日 用户投稿
    1000
  • 如何在Debian 10(Buster)Linux上安装MySQL

    了解如何在debian 10(buster)linux上安装mysql。本指南将引导您完成在最新版本的debian系统上安装mysql 8或mysql 5.7的步骤。 第1步 – 准备工作 首先,确保您拥有Debian 10系统的shell访问权限。如果是远程系统,可以通过SSH连接。W…

    2026年9月24日
    1000
  • sublime怎么去除购买弹窗_sublime关闭试用版购买提示的方法

    sublime怎么去除购买弹窗_sublime关闭试用版购买提示的方法sublime怎么去除购买弹窗_sublime关闭试用版购买提示的方法sublime怎么去除购买弹窗_sublime关闭试用版购买提示的方法sublime怎么去除购买弹窗_sublime关闭试用版购买提示的方法

    答案:可通过修改hosts文件、清理授权信息或降级版本缓解Sublime Text启动弹窗。具体操作包括屏蔽验证域名license.sublimehq.com、重命名Local目录下的Registry.dat文件,或安装旧版本并关闭更新提示,但建议支持正版以获得更好体验。 Sublime Text …

    2026年9月24日 用户投稿
    000
  • 对话非遗簪花传承人,华硕a豆携豆叮寻香泉州 国庆假期与未来香遇

    对话非遗簪花传承人,华硕a豆携豆叮寻香泉州 国庆假期与未来香遇对话非遗簪花传承人,华硕a豆携豆叮寻香泉州 国庆假期与未来香遇对话非遗簪花传承人,华硕a豆携豆叮寻香泉州 国庆假期与未来香遇对话非遗簪花传承人,华硕a豆携豆叮寻香泉州 国庆假期与未来香遇

    即日起至10月8日,时尚数码潮创先锋华硕a豆于福建泉州限时开启「与未来香遇」 “豆叮的寻香之旅”集章打卡活动,围绕茶桌仔、泉州鲤物、有鲤天台咖啡等三处特色地标打造沉浸式城市寻香狂欢;旗下ip豆叮以头戴非遗簪花的泉州限定皮肤萌力“占领”西街,延续上海安福路街区花车巡游派对的浪漫繁花景象,以“科技与非遗…

    2026年9月24日 用户投稿
    900
  • mysql存储过程在哪里写

    mysql存储过程在哪里写mysql存储过程在哪里写mysql存储过程在哪里写mysql存储过程在哪里写

    MySQL 存储过程存储在 MySQL 数据库中的 mysql.proc 表中。创建存储过程需要使用 CREATE PROCEDURE 语句,调用存储过程需要使用 CALL 语句。 MySQL 存储过程存储位置 存储过程在哪里写? MySQL 存储过程存储在 MySQL 数据库中。 详细说明: 存储…

    2026年9月24日 用户投稿
    500
  • AI音频工具有哪些_好用的AI音频工具大全

    AI音频工具有哪些_好用的AI音频工具大全AI音频工具有哪些_好用的AI音频工具大全AI音频工具有哪些_好用的AI音频工具大全AI音频工具有哪些_好用的AI音频工具大全

    ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜ 魔音工坊:AI配音神器,轻松打造媲美真人声线 讯飞智作:科大讯飞出品的语音转换与配音利器 听脑AI:智能语音记录助手 Suno:高品质AI音乐创作平台 海绵音乐:字节旗下免费AI音乐创作与探索平…

    2026年9月24日 用户投稿
    300
  • Java正则表达式:利用词边界实现精确的非贪婪字符串替换

    Java正则表达式:利用词边界实现精确的非贪婪字符串替换Java正则表达式:利用词边界实现精确的非贪婪字符串替换Java正则表达式:利用词边界实现精确的非贪婪字符串替换Java正则表达式:利用词边界实现精确的非贪婪字符串替换

    本教程探讨如何在Java中使用正则表达式精确替换字符串中的特定部分,特别是在目标字符串不应消耗后续字符的场景。通过分析常见错误,文章详细介绍了词边界的原理与应用,展示了如何利用它实现非贪婪且不破坏原字符串结构的替换,确保匹配的精确性与替换结果的完整性。 在处理字符串替换时,我们经常面临需要精确匹配特…

    2026年9月24日 用户投稿
    700
  • sublime怎么完全重置到初始状态_sublime恢复默认配置的步骤

    sublime怎么完全重置到初始状态_sublime恢复默认配置的步骤sublime怎么完全重置到初始状态_sublime恢复默认配置的步骤sublime怎么完全重置到初始状态_sublime恢复默认配置的步骤sublime怎么完全重置到初始状态_sublime恢复默认配置的步骤

    完全重置Sublime Text需先关闭程序,再删除系统中的Data目录:Windows路径为C:Users用户名AppDataRoamingSublime TextData,macOS为~/Library/Application Support/Sublime Text/Data,Linux为~/…

    2026年9月24日 用户投稿
    300
  • sublime怎么用快捷键关闭当前文件_sublime关闭标签页快捷操作

    sublime怎么用快捷键关闭当前文件_sublime关闭标签页快捷操作sublime怎么用快捷键关闭当前文件_sublime关闭标签页快捷操作sublime怎么用快捷键关闭当前文件_sublime关闭标签页快捷操作sublime怎么用快捷键关闭当前文件_sublime关闭标签页快捷操作

    答案是Ctrl+W(Windows/Linux)或Cmd+W(Mac)关闭当前标签页,前者适用于Windows和Linux系统,后者适用于macOS系统,符合各自平台操作习惯,可高效管理编辑界面。 在 Sublime Text 中关闭当前文件(即关闭标签页)可以通过快捷键快速完成,操作简单高效。 W…

    2026年9月24日 用户投稿
    100
  • Agent Zero— 开源可扩展AI框架,通过用户指令和任务动态学习

    Agent Zero— 开源可扩展AI框架,通过用户指令和任务动态学习Agent Zero— 开源可扩展AI框架,通过用户指令和任务动态学习Agent Zero— 开源可扩展AI框架,通过用户指令和任务动态学习Agent Zero— 开源可扩展AI框架,通过用户指令和任务动态学习

    agent zero 是一个开源的、可扩展的人工智能框架,能够作为用户的个性化智能助手。它不是基于预设功能的工具,而是通过用户指令和任务来动态学习与成长。agent zero 具备持久记忆能力,可以存储过往的解决方案、代码和事实信息,从而更快速地应对未来的任务。该框架将操作系统视为执行任务的工具,具…

    2026年9月24日 用户投稿
    100
  • 怎么在mysql中创建一个表 mysql新建数据表步骤教程

    在 mysql 中创建表的步骤和建议包括:1. 明确业务需求,设计表结构;2. 使用 create table 语句创建表,选择合适的数据类型和设置主键、索引;3. 考虑大数据量时使用分区;4. 设置正确的字符集和排序规则;5. 谨慎使用索引;6. 使用 if not exists 避免重复创建表。…

    2026年9月24日
    100
  • 主板 BIOS 功能深度对比:哪家超频与调校选项更丰富?

    主板 BIOS 功能深度对比:哪家超频与调校选项更丰富?主板 BIOS 功能深度对比:哪家超频与调校选项更丰富?主板 BIOS 功能深度对比:哪家超频与调校选项更丰富?主板 BIOS 功能深度对比:哪家超频与调校选项更丰富?

    答案是旗舰芯片组主板超频功能更强,具体取决于平台和型号。Intel的Z系列与AMD的X/B650E等高端主板提供完整超频选项,而B/H/A系列则限制较多;微星MPOWER系列在主流芯片组上提供越级超频工具;华硕、微星、技嘉三大品牌在BIOS设计上兼顾易用性与专业性,各具特色;最终选择需结合CPU支持…

    2026年9月24日 用户投稿
    000
  • Spring Boot @Nested 测试中属性覆盖与隔离策略

    Spring Boot @Nested 测试中属性覆盖与隔离策略Spring Boot @Nested 测试中属性覆盖与隔离策略Spring Boot @Nested 测试中属性覆盖与隔离策略Spring Boot @Nested 测试中属性覆盖与隔离策略

    本文深入探讨了在Spring Boot集成测试中,如何利用@Nested注解结合@TestPropertySource实现细粒度的属性配置和隔离。通过详细的示例代码,展示了外部测试类和嵌套测试类如何定义各自的属性集,以及这些属性在不同测试上下文中的继承与覆盖机制,从而确保测试环境的精确控制和独立性。…

    2026年9月24日 用户投稿
    100
  • 2025拼多多双11力度大吗?2025拼多多新版本

    2025拼多多双11力度大吗?2025拼多多新版本2025拼多多双11力度大吗?2025拼多多新版本2025拼多多双11力度大吗?2025拼多多新版本2025拼多多双11力度大吗?2025拼多多新版本

    拼多多2025年双11延续低价策略,升级百亿补贴、推出超级拼团2.0、发放直播神券、启用AR购物空间并扩容会员特权,覆盖iPhone、家电、美妆等品类,叠加多重优惠与互动玩法提升用户体验。 如果您计划在2025年双11期间购物,可能会关注拼多多此次大促的优惠幅度是否足够吸引人。今年拼多多延续了其“低…

    2026年9月24日 用户投稿
    000
  • mysql全文索引是什么意思

    mysql全文索引是什么意思mysql全文索引是什么意思mysql全文索引是什么意思mysql全文索引是什么意思

    MySQL 全文索引是一种特殊索引,用于提高全文搜索性能,通过存储单词的前缀来工作。它提供快速全文搜索、简易查询和部分匹配。要创建全文索引,可以使用 CREATE FULLTEXT INDEX 语法,例如:CREATE FULLTEXT INDEX index_name ON table_name …

    2026年9月24日 用户投稿
    100
  • sublime怎么安装字体并应用_sublime更换与应用新字体方法

    sublime怎么安装字体并应用_sublime更换与应用新字体方法sublime怎么安装字体并应用_sublime更换与应用新字体方法sublime怎么安装字体并应用_sublime更换与应用新字体方法sublime怎么安装字体并应用_sublime更换与应用新字体方法

    先在操作系统安装字体文件,再通过Sublime Text设置中的font_face指定字体名称即可应用。1. 将.ttf或.otf字体文件安装到系统:Windows右键安装,macOS双击后点击“安装字体”,Linux复制到~/.fonts并运行fc-cache -fv更新缓存。2. 重启Subli…

    2026年9月24日 用户投稿
    100

发表回复

登录后才能评论
关注微信