嵌入式学习 Day 24

1.exec函数族


    extern char **environ;

    int execl(const char *path, const char *arg, ...
                    /* (char  *) NULL */);
    int execlp(const char *file, const char *arg, ...
                    /* (char  *) NULL */);
    int execle(const char *path, const char *arg, ...
                    /*, (char *) NULL, char * const envp[] */);
    int execv(const char *path, char *const argv[]);
    int execvp(const char *file, char *const argv[]);
    int execvpe(const char *file, char *const argv[],
                    char *const envp[]);

    功能:
        利用进程空间执行另外一份代码
    
    l:参数以列表形式传递
    v:参数以指针数组形式传递
    e:更新环境变量
    p:在系统指定目录下查找文件

 注意:

execl 默认在当前目录下寻找

或者

execlp默认在系统目录下寻找

更改路路径到当前目录

或者

    getenv
    char *getenv(const char *name);
    功能:
        获得环境变量名对应的值
    
    setenv
    int setenv(const char *name, const char *value, int overwrite);
    功能:
        设置环境变量的值
    参数:
        name:环境变量名
        value:环境变量的值
        overwrite:非0 覆盖
                  0   不覆盖
    返回值:
        成功返回0 
        失败返回-1 
       

 

2.线程:


    1.基本概念:

        线程:线程是一个轻量级的进程,位于进程空间内部,一个进程中可以创建多个线程

    2.线程创建:

        线程独占一个栈空间, 文本段、数据段和堆区与进程共享


    3.线程调度:

        与进程调度是一样的
        宏观并行,微观串行 


    4.线程消亡:

        与进程消亡是一样的

    5.进程和线程的区别:

        进程是操作系统资源分配的最小单元
        线程是CPU任务调度的最小单元

 

    6.函数和线程的区别:

       被调函数执行完后主函数才继续向下执行

       线程在被创建后和进程同时向下执行

    7.多进程和多线程的优缺点:


        效率 : 多线程 > 多进程 

             多线程只需在同一进程空间内切换
             多进程需要在不同的空间中切换        


        通信 : 多线程 > 有进程

            线程共享全局变量,可以通过全局变量实现数据通信
            进程空间是独立的,没有共享空间,通信实现比较复杂

        通信实现 : 多进程 > 多线程

            线程共享空间操作时会引发资源竞争(通过使用时上锁,使用后解锁来解决)
            进程没有共享空间,不存在资源竞争的问题      


        安全 : 多进程 > 多线程

            一个进程异常不会影响其余进程空间
            一个线程异常结束会导致进程异常结束,进程异常结束,该进程内所有线程任务均无法向下执行    


    8.线程相关的函数接口:

        创建: fork      pthread_create 
        退出: exit      pthread_exit 
        回收: wait      pthread_join 

        1.pthread_create


          int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                          void *(*start_routine) (void *), void *arg);
          功能:
            在该进程中创建一个新的线程
          参数:
            thread:存放线程ID空间首地址
            attr:线程属性空间首地址
            start_routine:线程要执行的函数的入口
            arg:给线程函数的参数
          返回值:
            成功返回0 
            失败返回错误码

        编译时加 -lpthread选项  

        2.pthread_self


          pthread_t pthread_self(void);
          功能:
            获得调用该函数线程的ID      

        3.pthread_exit 


          void pthread_exit(void *retval);
          功能:
            让调用该函数的线程任务结束
          参数:
            retval:线程结束的值


        4.pthread_join 


          int pthread_join(pthread_t thread, void **retval);
          功能:
            回收线程空间
          参数:
            thread:线程的ID号
            retval:存放线程结束状态空间的首地址
          返回值:
            成功返回0 
            失败返回错误码

3.何时用到二级指针(题外话)

1.指针数组传参时,用到二级指针

   指针数组是一个包含多个指针元素的数组。每个指针元素可以指向不同的数据类型或数据结构。通过传递指针数组的地址(即指针数组的数组名),被调函数可以直接访问和修改数组中的元素。

#include <stdio.h>

// 函数原型,接受一个指针数组作为参数
void printPointers(int *ptrArr[], int size) 
{
    for (int i = 0; i < size; i++)
    {
        printf("%p\n", ptrArr[i]);
    }
}

int main()
{
    int num1 = 10;
    int num2 = 20;
    int num3 = 30;

    // 定义一个指针数组,包含三个整型指针
    int *ptrArr[] = {&num1, &num2, &num3};

    // 将指针数组传递给函数
    printPointers(ptrArr, 3);

    return 0;
}

定义了一个指针数组 ptrArr,其中包含三个整型指针,分别指向变量 num1num2num3。然后,我们将指针数组传递给 printPointers 函数,它会遍历指针数组并打印每个指针的地址。 

2.被调修改主调时,用到二级指针

    函数传参是值传递,形参只是实参的副本,形参值如何变化不影响实参的值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值