2.6exec函数族

本文详细介绍了C语言中的execl和execlp函数,讲述了它们在子进程启动中的应用,包括文件路径查找、参数传递以及执行失败的返回机制。重点讲解了如何通过这两个函数替换子进程代码并利用环境变量寻找可执行文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

函数族:一系列功能相同或相似的函数

p是代表到环境变量中找,e表示给程序新的环境变量。

前六个是标准c库函数,最后一个是linux库函数

常用execl和execlp

1.execl函数

子进程的代码被替换掉

 

/*
    #include <unistd.h>
    extern char **environ;
    int execl(const char *path, const char *arg, ...);
        -参数:
            -path:需要指定的执行的文件的路径或名称
                相对路径:a.out 绝对路径:/hone/ethan/a.out 推荐使用绝对路径

            -arg:是执行可执行文件苏需要的参数列表
                第一个参数一般没有什么作用为了方便,一般写的是执行的程序的名称
                从第二个参数开始往后,就是程序执行所需要的参数列表
                参数最后需要以NULL结束(哨兵)
                类似./a.out hello
        -返回值:
            只有当调用失败,才会有返回值,返回-1,并且设置errno
            
*/
#include <unistd.h>
#include <stdio.h>
int main(){
    //创建一个子进程,在子进程中执行exec函数族中的函数
    pid_t pid = fork();
    if(pid>0){
        //父进程
        printf("i am parent process, pid : %d\n",getpid());
        sleep(1);
    }
    else if(pid==0){
        //子进程
        //execl("/home/ethan/Linux/lesson19/hello","hello",NULL);

        //shell命令执行
        execl("/bin/ps","ps","aux",NULL);
        printf("i am child process pid = %d\n",getpid());
    }
    
    for(int i=0;i<3;i++)
    {
        printf("i = %d, pid = %d\n",i,getpid());
    }
    return 0;
}

2.execlp函数: 

/*
    #include <unistd.h>
    extern char **environ;
        int execlp(const char *file, const char *arg, ...);
        -会到环境变量中查找指定的可执行文件,如果找到了就执行,找不到就执行不成功
        -参数:
            -file:需要执行的可执行的文件名
                a.out
                ps

            -arg:是执行可执行文件苏需要的参数列表
                第一个参数一般没有什么作用为了方便,一般写的是执行的程序的名称
                从第二个参数开始往后,就是程序执行所需要的参数列表
                参数最后需要以NULL结束(哨兵)
                类似./a.out hello
        -返回值:
            只有当调用失败,才会有返回值,返回-1,并且设置errno
            
*/
#include <unistd.h>
#include <stdio.h>
int main(){
    //创建一个子进程,在子进程中执行exec函数族中的函数
    pid_t pid = fork();
    if(pid>0){
        //父进程
        printf("i am parent process, pid : %d\n",getpid());
        sleep(1);
    }
    else if(pid==0){
        //shell命令执行
        execlp("ps","ps","aux",NULL);
        //如果是hello自己写的代码由于环境变量中没有会出错
        printf("i am child process pid = %d\n",getpid());
    }
    
    for(int i=0;i<3;i++)
    {
        printf("i = %d, pid = %d\n",i,getpid());
    }
    return 0;
}

在编程中,`slot` 的概念广泛应用于前端框架(如 Vue.js)和 GUI 开发(如 Qt),用于实现组件间通信或事件处理。根据不同的上下文,传递参数的方式也有所不同。 ### 在 Vue.js 中使用插槽传递参数 Vue 2.6+ 引入了 `v-slot` 指令来统一处理默认插槽与具名插槽,并支持向插槽作用域中传递数据。这种方式被称为作用域插槽。 #### 示例:作用域插槽传递参数 子组件中定义插槽并绑定数据: ```vue <!-- ChildComponent.vue --> <template> <div> <slot :user="user" :age="age"></slot> </div> </template> <script> export default { data() { return { user: 'Alice', age: 25 }; } }; </script> ``` 父组件中使用插槽并接收参数: ```vue <!-- ParentComponent.vue --> <template> <child-component v-slot="{ user, age }"> <p>{{ user }} is {{ age }} years old.</p> </child-component> </template> ``` 在这个例子中,子组件通过插槽传递了 `user` 和 `age` 数据,父组件则通过解构语法接收这些数据并在模板中使用[^2]。 ### 在 Qt 中使用信号与槽传递参数 Qt 提供了强大的信号与槽机制,允许在不同对象之间传递参数。从 Qt 5 开始,推荐使用 Lambda 表达式或函数指针形式的 `connect` 语法来连接信号与槽。 #### 示例:使用 Lambda 表达式传递参数 ```cpp #include <QApplication> #include <QPushButton> #include <QLabel> #include <QVBoxLayout> #include <QWidget> int main(int argc, char *argv[]) { QApplication app(argc, argv); QWidget window; QVBoxLayout *layout = new QVBoxLayout(&window); QLabel *label = new QLabel("No button clicked", &window); layout->addWidget(label); QPushButton *button = new QPushButton("Click me", &window); layout->addWidget(button); // 使用 Lambda 表达式捕获 label 并修改其文本 QObject::connect(button, &QPushButton::clicked, [=]() { label->setText("Button clicked!"); }); window.show(); return app.exec(); } ``` 在这个例子中,当按钮被点击时,Lambda 表达式会被执行,并修改标签的文本内容。通过 `[=]` 捕获列表,可以将外部变量以值传递的方式引入到 Lambda 函数内部使用[^1]。 #### 示例:自定义 QAction 控件传递参数 如果需要在菜单项或工具栏按钮中传递参数,可以通过继承 `QAction` 并添加自定义属性和信号来实现。 ```cpp // CustomAction.h #ifndef CUSTOMACTION_H #define CUSTOMACTION_H #include <QAction> #include <QString> class CustomAction : public QAction { Q_OBJECT public: explicit CustomAction(const QString &name, QObject *parent = nullptr) : QAction(name, parent), name_(name) { connect(this, &QAction::triggered, this, &CustomAction::sendClicked); } ~CustomAction() { disconnect(this, &QAction::triggered, this, &CustomAction::sendClicked); } private slots: void sendClicked() { emit myClicked(name_); } signals: void myClicked(const QString &name); // 发送名称 private: QString name_; }; #endif // CUSTOMACTION_H ``` 在主窗口中使用该自定义动作并连接信号与槽: ```cpp CustomAction *action = new CustomAction("File Open"); connect(action, &CustomAction::myClicked, [=](const QString &name) { qDebug() << "Action clicked:" << name; }); ``` 此方式通过自定义 `QAction` 类,实现了在触发动作时传递字符串参数的功能[^5]。 ### 总结 - **Vue.js** 中的作用域插槽允许父组件访问子组件传递的数据,并在插槽内容中使用这些数据。 - **Qt** 中的信号与槽机制支持多种方式传递参数,包括 Lambda 表达式、自定义控件等。 以上方法分别适用于前端开发与 GUI 编程场景下的参数传递需求。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值