exec函数族 和 线程 学习

一.exec函数族

    extern char **environ;

    int execl(const char *path, const char *arg, ...    (后面跟的参数)
                    /* (char  *) NULL */);

eg:

int main(void)                  //execl用法
{printf("======================");execl("./hello","./hello","艳阳","高照",NULL);       //后面跟的“传参”的参数,优先在当前目录来找return 0;
}


    int execlp(const char *file, const char *arg, ...   (区别l在于在哪个目录下寻找需要执行的文件)
                    /* (char  *) NULL */);

eg:

extern char **environ;            //execlp的用法
int main(void)
{int i = 0;char tmpbuff[1024] = {0};printf("===================/n");for (i = 0; environ[i] != NULL; i++){printf("environ[%d] = %s\n", i, environ[i]);      //打印程序运行时的隐藏运行文件}printf("===================\n");printf("PATH:%s\n",getenv("PATH"));   //获取PATH中的路径,此时是未改变的路径,是优先在系统下寻找printf("===================\n");getcwd(tmpbuff,sizeof(tmpbuff));       //获取当前路径setenv("PATH",tmpbuff,1);             //将原本为改变的路径更改为获取的当前路径经,代表在当下路径寻找文件printf("PATH:%s\n",getenv("PATH"));   //验证更改后的路径printf("===================\n");execlp("hello","hello","艳阳","高照",NULL);return 0;
}


    int execle(const char *path, const char *arg, ...
                    /*, (char *) NULL, char * const envp[] */);
    int execv(const char *path, char *const argv[]);

eg:

int main(void)                  //execv用法
{char *ch[10] = {"./hello","艳阳","高照",NULL};printf("======================");execv("./hello",ch);       //后面跟的指针数组首地址,优先在当前目录寻找return 0;
}


    int execvp(const char *file, char *const argv[]);

eg:

int MySystem(const char *pcommand)           //函数,实现调用ls功能
{char commandbuf[1024] = {0};char *parg[10] = {NULL};int cnt = 0;pid_t pid;strcpy(commandbuf,pcommand);             //pcommand是一个常量,要变量才能使用strtok,所以将它放在数组中parg[cnt] = strtok(commandbuf," ");     //第一次分割字符串放在parg【0】中cnt++;while((parg[cnt] = strtok(NULL," "))!=NULL)  //后续分割,当返回值为NULL代表识别不到,停止{cnt++;}pid = fork();                //建立子程序用来执行execvp,以防父程序用完execvp后程序结束,无法执行后面的if(pid == -1){perror("fail to fork");return -1;}if(pid == 0){execvp(parg[0],parg);   //parg[0]是一个ls功能,在bin中储存,parg是一个指针数组,存放的指令}wait(NULL);  //回收子进程空间return 0;
}int main(void)
{printf("shang\n");      //测试主程序运行MySystem("ls -l");      //调用函数printf("xia\n");        //测试主程序运行return 0;}


    int execvpe(const char *file, char *const argv[],
                    char *const envp[]);

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

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

二.线程

1.概念:

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

2.线程的创建:

线程独占 栈空间,文本段,数据段和堆区与进程程序

3.线程调度:

与进程调度是一样的,宏观并行,围观穿行

4.线程的消亡:

与进程消亡是一样的

5.进程和线程的区别:

                                   进程是操作系统资源分配的最小单元
                                   线程是CUP任务调度的最小单元
                                   多个线程的任务调度的时候比进程更加节省资源空间

6.多进程多线程的优缺点:

               从效率来说:多线程 > 多线程  ---   多线程只需要在同一进程空间切换,多进程需要在不同的空间切换
              通信:多线程 > 多进程 --- 线程共享全局变量,可以通过全局变量实现数据通信  ; 
进程空间是独立的,没有共享空间,通信实现比较复杂
               通信实现:多进程 > 多线程 --- 线程共享空间操作时引发资源竞争  ;  进程没有共享空间,不存在资源竞争的问题
              安全:多进程 > 多线程 --- 一个进程异常不会影响到其余空间 ; 一个线程异常结束会导致进程进程异常结束 , 进程异常结束 , 该进程内所有线程所有线程任务均无法向下执行。

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

创建: pthread_create 
退出: pthread_exit 
回收: 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  

练习:创建三个线程任务,线程打印 线程(TID:XXXX)开始执行------------------------------------------------

void *threadfun1(void *arg)              //线程执行的函数入口1
{printf("线程1(TID:%#x)开始运行!\n",(unsigned int)pthread_self());return NULL;}
void *threadfun2(void *arg)              //线程执行的函数入口2
{printf("线程2(TID:%#x)开始运行!\n",(unsigned int)pthread_self());return NULL;}
void *threadfun3(void *arg)              //线程执行的函数入口3
{printf("线程3(TID:%#X)开始运行!\n",(unsigned int)pthread_self());return NULL;}int main(void)
{int ret = 0;int i = 0;pthread_t tid[3];void *(*th[10])(void *) = {threadfun1,threadfun2,threadfun3};  //函数指针数组for(i=0;i<3;i++){ret = pthread_create(&tid[i],NULL,th[i],NULL);if(ret != 0){perror("fail to pthread_create");return -1;}}while(1){}return 0;}

          3.pthread_exit 

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

          4.pthread_join 

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

eg:pthread_exit,pthread_join 用法示例

void *thread(void *arg)
{printf("线程(TID: %#x)开始运行\n",(unsigned int)pthread_self());sleep(3);printf("线程即将结束\n");pthread_exit("Game Over!");          //线程任务的结束return NULL;
}int main(void)
{pthread_t tid;void *arg = NULL;pthread_create(&tid,NULL,thread,NULL);  //线程任务的开始pthread_join(tid,&arg);           //1参数:线程的ID号,2参数:存放线程结束状态空间的首地址printf("arg = %s\n",(char *)arg);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/704904.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

nginx管理命令

nginx管理命令 ngnix作用是多个进程处理网络请求。一部分是管理命令&#xff0c;一部分是配置文件。 nginx管理命令 两种管理方式nginx管理和systemctl管理&#xff0c;注意使用哪种方式开始就用哪种方式结束。 1. nginx管理方式 nginx -t : 检测nginx.conf配置文件的语法 …

【项目管理需求分析】环境决定了你能看到什么

文章目录 前言基层的痛1.业务提不出需求2.建议不可取 总结 前言 近期工作中有所感悟&#xff0c;乘着春节的尾巴不是很忙&#xff0c;就记录下来。 随着公司的不断扩大&#xff0c;总公司、省公司、市公司、县公司&#xff5e;&#xff0c;纵向越来越深&#xff0c;科技专业人…

react脚手架

1.react概述 1.1 什么是react React是一个用于构建用户界面的JS库。 用户界面&#xff1a;HTML页面&#xff08;前端&#xff09; React主要用来写HTML界面&#xff0c;或构建Web应用 如果从MVC的角度来看&#xff0c;React仅仅是视图层&#xff08;V&#xff09;,也就是只负…

亿道丨三防平板丨手持平板丨加固平板丨助力地震救援

自土耳其发生7.8级大地震以来&#xff0c;一直都牵动着世人的心。2023年2月10日&#xff0c;据法新社最新消息&#xff0c;强震已造成土耳其和叙利亚两国超2万人遇难。报道称&#xff0c;相关官员和医护人员表示&#xff0c;地震造成土耳其17674人死亡&#xff0c;叙利亚则有33…

Nginx+Tomcat实现动静分离

文章目录 一.动静分离的原理及架构1.1 动静分离是什么&#xff1f;1.2 动静分离的原理1.3 动静分离的架构组成 二.NginxTomcat实现动静分离2.1实验环境2.2所需软件环境2.3nginx服务的实现2.4配置动静分离 一.动静分离的原理及架构 1.1 动静分离是什么&#xff1f; 动静分离(S…

Nginx的核心配置指令及调优

目录 Nginx 核心配置指令 一、Nginx配置文件详解 1、配置文件目录 2、配置文件结构 二、调优 1、在全局域进行的调优 1.1线程池指令 1.2 工作进程数指令 1.3工作进程优先级指令 1.4 工作进程 CPU 绑定指令 1.5 调试可打开的文件个数 1.6 调试文件大小指令 1.7 只运…

FL Studio Fruity Edition2024中文入门版Win/Mac

FL Studio Fruity Edition2024是一款功能强大的音乐制作软件&#xff0c;适合初学者和音乐爱好者使用。它提供了丰富的音乐制作工具&#xff0c;包括音频录制、编辑、混音以及MIDI制作等功能&#xff0c;帮助用户轻松创作出动人的音乐作品。 FL Studio 21.2.3 Win-安装包下载如…

《数据治理简易速速上手小册》第1章 数据治理概述(2024 最新版)

文章目录 1.1 数据治理的定义与重要性1.1.1 基础知识1.1.2 重点案例&#xff1a;客户数据分析1.1.3 拓展案例 1&#xff1a;库存管理系统1.1.4 拓展案例 2&#xff1a;合规性数据报告 1.2 数据治理的发展历程1.2.1 基础知识1.2.2 重点案例&#xff1a;电商平台的用户数据管理1.…

苍穹外卖 -- day10- Spring Task- 订单状态定时处理- WebSocket- 来单提醒- 客户催单

苍穹外卖-day10 功能实现&#xff1a;订单状态定时处理、来单提醒和客户催单 订单状态定时处理&#xff1a; 来单提醒&#xff1a; 客户催单&#xff1a; 1. Spring Task 1.1 介绍 Spring Task 是Spring框架提供的任务调度工具&#xff0c;可以按照约定的时间自动执行某个代…

稀疏表示分类(Sparse Representation for Classification,SRC)

稀疏表示分类&#xff08;Sparse Representation for Classification&#xff0c;简称SRC&#xff09;是一项在模式识别和信号处理中应用广泛的技术。它基于这样一个概念&#xff1a;一个信号&#xff08;比如图像、语音等&#xff09;可以用一个较大的字典中的一些基向量稀疏地…

WebServer -- 日志系统(上)

目录 &#x1f92b;基础知识 &#x1f382;整体概述 &#x1f33c;单例模式 懒汉 -- 双检锁 懒汉 -- 局部静态变量 饿汉 &#x1f33c;条件变量 && 生产/消费者模型 条件变量 API 与 陷阱 基础 API 陷阱一 陷阱二 生产/消费者 模型 &#x1f382;阻塞队列…

SpringCache缓存专题

SpringCache缓存专题 学习目标 1、理解缓存存在的意义 2、掌握redis与SpringCache的集成方式 3、掌握SpringCache注解的使用 4、掌握项目集成SpringCache流程 第一章 基于SpringCache缓存方案 1.为什么需要缓存 ​ 前台请求&#xff0c;后台先从缓存中取数据&#xff0…

浅析ARMv8体系结构:原子操作

文章目录 概述LL/SC机制独占内存访问指令多字节独占内存访问指令 独占监视器经典自旋锁实现 LSE机制原子内存操作指令CAS指令交换指令 相关参考 概述 在编程中&#xff0c;当多个处理器或线程访问共享数据&#xff0c;并且至少有一个正在写入时&#xff0c;操作必须是原子的&a…

uniapp的微信小程序授权头像昵称(最新版)

前面我出过两期博客关于小程序授权登录,利用php实现一个简单的小程序授权登录并存储授权用户信息到数据库的完整流程。无奈&#xff0c;小程序官方又整幺蛾子了。wx.getUserInfo接口收回&#xff0c;wx.getUserProfile接口也不让用。导致我的个人小程序&#xff1a;梦缘 的授权…

Linux设备模型(五) - uevent kernel实现

1. Uevent的功能 Uevent是Kobject的一部分&#xff0c;用于在Kobject状态发生改变时&#xff0c;例如增加、移除等&#xff0c;通知用户空间程序。用户空间程序收到这样的事件后&#xff0c;会做相应的处理。 该机制通常是用来支持热拔插设备的&#xff0c;例如U盘插入后&…

APIFox-自动获取登录状态操作

APIFox-自动获取登录状态操作 概述 作为纯后端开发码农&#xff0c;每次接口开发完的调试很重要&#xff0c;因此每次重复的手动获取登陆状态Token或者直接放行就太麻烦了。 APIFox提供了前置操作&#xff0c;可以很方便的自动获取登录状态&#xff0c;节省大量重复劳动时间。…

《TCP/IP详解 卷一》第7章 防火墙和NAT

7.1 引言 NAT通常改变源IP和源端口&#xff0c;不改变目的IP和目的端口。 7.2 防火墙 常用防火墙&#xff1a; 包过滤防火墙&#xff08;packet-filter firewall&#xff09; 代理防火墙&#xff08;proxy firewall&#xff09; 代理防火墙作用&#xff1a; 1. 通过代理服务…

新手怎么使用github?

GitHub新手使用指南&#xff0c;涵盖了从注册、创建仓库、版本控制基本操作到SSH密钥配置等关键步骤&#xff1a; 第一步&#xff1a;注册与登录 访问GitHub官方网站&#xff1a;https://github.com。点击页面右上角的"sign up"按钮开始注册账号。输入有效的电子邮…

React_使用es5和es6语法渲染和添加class

React入门 //react的核心库 <script src"https://cdn.jsdelivr.net/npm/react17/umd/react.development.js"></script> //react操作dom的核心库&#xff0c;类似于jquery <script src"https://cdn.jsdelivr.net/npm/react-dom17/umd/react-dom.…