【Docker】Docker镜像结构及自定义镜像,镜像上传仓库使用

news2024/11/22 21:30:54

一、引言

        Docker镜像是一个只读的Docker容器模板,含有启动Docker容器所需的文件系统结构及其内容,因此是启动一个Docker容器的基础。镜像的结构原理图大致分为四层:共享的内核层、基础镜像层、定制镜像层、可写容器层。

  1. 共享的内核层:每个Docker容器运行时都共享宿主机的内核,这样可以大大减少内存的开销。
  2. 基础镜像层:base镜像提供的是最小的linux发行版,其实就是linux的根/文件系统。
  3. 定制镜像层:基于基础镜像进行定制化,添加或删除某些内容,形成新的镜像。
  4. 可写容器层:当一个容器被运行时,实际上会在这最后一层上运行,因此这一层是可以写的,能对容器进行动态的改变。

采用分层结构的最大好处是“共享资源”,不同的镜像使用同一个镜像层的时候,文件系统便可以实现资源共享,只需要备份一次,节省空间。

二、镜像结构

自定义 Docker 镜像有很多用途,以下是一些主要的应用场景:

  1. 一致性环境:通过自定义镜像,您可以确保您的应用在不同的环境中(开发、测试、生产等)运行在完全一致的环境中。这可以避免"在我机器上可以运行"的问题。

  2. 快速部署:自定义镜像包含了运行应用所需的所有依赖,这使得部署过程变得非常快速和简单。只需运行一个命令,就可以在任何安装了 Docker 的机器上启动应用。

  3. 版本控制和回滚:每个 Docker 镜像都有一个唯一的标签,这使得版本控制变得非常简单。如果新版本的应用有问题,您可以很容易地回滚到旧版本的镜像。

  4. 微服务架构:在微服务架构中,每个服务都可以有自己的 Docker 镜像。这使得每个服务可以独立地更新和扩展,而不会影响其他服务。

  5. 持续集成/持续部署(CI/CD):在 CI/CD 管道中,自定义镜像可以用于构建、测试和部署应用。这使得整个开发过程更加自动化,提高了开发效率。

Ⅰ. 基本结构

Dockerfile 是一个文本文件,它包含了一组用户可以调用来创建镜像的指令。以下是 Dockerfile 的基本结构:

  1. FROM:指定基础镜像,所有操作都基于这个基础镜像。例如:FROM ubuntu:18.04

  2. LABEL:为镜像添加元数据及声明镜像的作者或者维护者的信息。

  3. RUN:在镜像中运行命令,这些命令会在新的层上创建新的镜像。例如:RUN apt-get update

  4. CMD:提供容器默认的可执行程序,可以包含可执行程序,也可以省略,如果省略,则必须在运行时通过命令行指定。例如:CMD ["executable","param1","param2"]

  5. EXPOSE:声明运行时容器提供服务的网络端口。例如:EXPOSE 8080

  6. ENV:设置环境变量。例如:ENV myName="John Doe" myDog=Rex\ The\ Dog

  7. ADD 和 COPY:将文件从 Docker 主机复制到 Docker 镜像中。ADD 有自动解压缩功能,COPY 则更为直接明了。

  8. ENTRYPOINT:配置容器启动后执行的命令,并且不会被 docker run 提供的参数覆盖。

  9. VOLUME:创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保存的数据等。

  10. WORKDIR:设置工作目录,所有后续的操作(CMD、ENTRYPOINT、COPY 和 ADD)都会在这个目录下进行。

  11. USER:设置运行容器时的用户名或 UID。

  12. ONBUILD:当构建一个被继承的 Dockerfile 时运行命令,该指令添加到镜像中,稍后触发。

  13. MAINTAINER :用于声明镜像的作者或者维护者的信息,它可以为使用者提供一种联系镜像创建者的方式。

【注意i】MAINTAINER 从 Docker 1.13.0 开始,这个指令已经被标记为已废弃,推荐使用 LABEL 指令来替代。

如:

MAINTAINER John Doe <john.doe@example.com>

 如:

LABEL maintainer="John Doe <john.doe@example.com>"

LABEL 指令可以用于添加更多的元数据到镜像中,比如版本号、构建日期等等。

这些指令在 Dockerfile 中按照从上到下的顺序执行。每个指令都会在镜像上创建一个新的层,然后提交。

案例:

# 基于官方的 JDK 镜像
FROM openjdk:8-jdk
# 设置环境变量
ENV CATALINA_HOME /usr/local/tomcat
ENV PATH $CATALINA_HOME/bin:$PATH
# 安装 MySQL
RUN apt-get update && apt-get install -y mysql-server
# 安装 Tomcat
RUN mkdir -p "$CATALINA_HOME"
WORKDIR $CATALINA_HOME
RUN curl -O https://downloads.apache.org/tomcat/tomcat-8/v8.5.61/bin/apache-tomcat-8.5.61.tar.gz \
&& tar -xvf apache-tomcat-8.5.61.tar.gz \
&& rm apache-tomcat-8.5.61.tar.gz
# 暴露端口
EXPOSE 8080
# 启动 Tomcat
CMD ["catalina.sh", "run"]

这个 Dockerfile 会创建一个包含 JDK、MySQL 和 Tomcat 的 Docker 镜像。在构建镜像时,它会先从 Docker Hub 下载官方的 JDK 镜像作为基础镜像,然后安装 MySQL,接着下载并安装 Tomcat,最后设置启动命令为启动 Tomcat。

请注意,这只是一个基础示例,实际使用时可能需要根据具体需求进行修改和优化。例如,可能需要添加更多的环境变量,或者调整安装命令以适应特定的应用需求。

Ⅱ. 常用命令

以下是您提到的 Dockerfile 指令的详细解释:

  1. RUN:用于执行后面跟着的命令行命令。有两种格式:RUN <command>(shell 格式)和 RUN ["executable", "param1", "param2"](exec 格式)。

  2. ENV:用于设置环境变量。这些变量以 <key>=<value> 的形式存在,可以在容器中被脚本或程序调用。

  3. COPY:将来自 Dockerfile 所在目录的文件或目录复制到容器中的一个新位置。

  4. ADD:与 COPY 类似,但是 ADD 允许后面的源参数是一个 URL,或者在源文件是一个 tar 文件的情况下,可以自动解压缩这个 tar 文件。

  5. EXPOSE:用于声明容器运行时监听的网络端口。

  6. WORKDIR:用于设置 RUN、CMD、ENTRYPOINT、COPY 和 ADD 指令的工作目录。

  7. ONBUILD:当镜像被用作其他 Dockerfile 的基础镜像时,ONBUILD 指令将会被触发执行。

  8. USER:用于设置接下来的 RUN、CMD 和 ENTRYPOINT 指令运行时的 UID。

  9. VOLUME:用于在容器中创建一个挂载点,用于连接 Docker 主机和容器的文件系统。

容器启动时自动执行指令:

CMD 和 ENTRYPOINT 都是 Dockerfile 中用于指定容器启动时运行的命令的指令,但它们的用法和目的有所不同。

  1. CMD:CMD 指令用于提供容器运行时的默认命令及其参数。在启动容器时,我们可以覆盖这些默认的参数。CMD 在 Dockerfile 中只应被定义一次,如果定义了多次,只有最后一次的定义会生效。CMD 有两种格式:

    如果 Dockerfile 中同时存在 CMD 和 ENTRYPOINT,CMD 中的参数会被添加到 ENTRYPOINT 中,作为其参数。

    • CMD ["executable","param1","param2"](exec 格式,推荐)
    • CMD command param1 param2(shell 格式)
  2. ENTRYPOINT:ENTRYPOINT 的目的也是让容器以应用程序或服务的形式运行。与 CMD 不同,我们在启动容器时不能覆盖 ENTRYPOINT 指令提供的命令,但可以添加额外的参数。ENTRYPOINT 有两种格式:

    如果我们既想让容器以应用程序或服务的形式运行,又想让这些应用或服务接受参数,那么最好的做法是使用 ENTRYPOINT 和 CMD 一起使用,让 ENTRYPOINT 指定应用程序,而让 CMD 指定默认参数。

    • ENTRYPOINT ["executable", "param1", "param2"](exec 格式,推荐)
    • ENTRYPOINT command param1 param2(shell 格式)

三、自定义镜像

Ⅰ. 基本镜像

首先进入虚拟机并且用MobaXterm这个工具连接,进入后先查看docker的服务/进程有没有开:

输入命令:systemctl status docker   (查看docker的服务/进程)

以下是没有开启状态:

 以下是开启状态:

创建一个文件夹,来存放创建后的镜像,并且创建并编写 Dockerfile 文件。

创建文件夹:mkdir soft      (名称soft,可以自己修改)

进入文件夹:cd soft/

创建并编辑Dockerfile文件:vim Dockerfile    (文件名称不用改)

进入文件后,按 i 进入编辑模式,然后将以下粘贴上,在按Esc退出编辑模式,输入 :wq 

保存编写内容并且退出文件。 

Dockerfile文件中编写:

#1.指定基础镜像,并且必须是第一条指令
FROM  centos
#2.指明该镜像的作者和其电子邮件
MAINTAINER  CloudJun  "jun737x@163.com"
#3.在构建镜像时,指定镜像的工作目录,之后的命令都是基于此工作目录,如果不存在,则会创建目录
WORKDIR  /test
#4.将文件从Docker主机复制到Docker镜像中
COPY spring.jar /test

创建编写完成后,通过 docker build 命令来创建镜像。

命令:

docker build -t spring:v1

创建语句 docker build -t ,创建后这个镜像的名称spring,这个镜像的版本为 v1 ( 版本可以自己定义,如:0.1,1.0,v1,v2都可以),其中的  . 表示在当前目录创建

再查看镜像:docker images 

进入:docker run -it spring:v1 (spring为镜像名称,后面的:v1是需要进入镜像的哪个版本)

之后看看当前目录是不是自己在Dockerfile文件中所设置的,及带进来的jar包是否存在

查看当前路径:pwd 

查看文件:ls 

Ⅱ. 进阶镜像

以上的镜像是不可以jar包中的项目运行的,因为镜像中没有jdk配置。

首先,需将本地的属于Linux的jdk和jre的压缩包拖到创建的文件夹中

如图:

以下我们来进行完善以上的缺陷: 

以下配置jdk,可以运行jar包项目

输入命令,编辑Dockerfile文件:vim Dockerfile   ,将原来的编写全部删除。

删除:进入后先将输入键到第一行,再输入数字(输入的数字是看不到的如:12),再按两下 d ,就会删除12行已编写的内容,当然输入13或者14就删除13或者14行,可以根据自己想删除多少行来进行输入

将以下编写的内容粘贴到Dockerfile文件中,按Esc退出编辑模式,输入 :wq 保存编写内容并且退出文件。 

#1.指定基础镜像,并且必须是第一条指令
FROM  centos
#2.指明该镜像的作者和其电子邮件
MAINTAINER  CloudJun  "jun737x@163.com"
#3.在构建镜像时,指定镜像的工作目录,之后的命令都是基于此工作目录,如果不存在,则会创建目录
WORKDIR  /test
#4.将文件从Docker主机将jdk及jar包复制到Docker镜像中,自动将jdk的压缩包进行解压
COPY  spring.jar /test
ADD  jdk-8u221-linux-x64.tar.gz  /test
#5.将jdk解压后配置环境变量
ENV JAVA_HOME=/test/jdk1.8.0_221
ENV CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV PATH=$JAVA_HOME/bin:$PATH
#6.容器启动时,需要执行的命令(执行jar包)
CMD java -jar spring.jar

如图(粘贴进去后全部注释了,可以手动删除前面的#解除注释): 

创建镜像:

docker build -t spring:v2

  

再查看镜像:

docker images

进入容器:

docker run -it spring:v2

      (这里会自动启动jar包)

已可以通过:

docker run -itd spring:v2

   (在后台运行)

再进入:docker exec -it 24696887b11eeb7ea229221e94f7b0cac03526551854319db80aef21b2d12ca4 bash

( 其中bash前面是运行后的编号,根据运行后的编号进入到该容器中)

查看jar及解压后的jdk,还可以输入命令查看jdk环境:echo $JAVA_HOME

以下配置jre,可以运行jar包项目及优化储存

输入命令,编辑Dockerfile文件:vim Dockerfile   ,将原来的编写全部删除。

将以下编写的内容粘贴到Dockerfile文件中,按Esc退出编辑模式,输入 :wq 保存编写内容并且退出文件。 

#1.指定基础镜像,并且必须是第一条指令
FROM  centos
#2.指明该镜像的作者和其电子邮件
MAINTAINER  CloudJun  "jun737x@163.com"
#3.在构建镜像时,指定镜像的工作目录,之后的命令都是基于此工作目录,如果不存在,则会创建目录
WORKDIR  /test
#4.将文件从Docker主机jre包复制到Docker镜像中,自动将jdk的压缩包进行解压
COPY  spring.jar /test
ADD  jre-8u391-linux-x64.tar.gz  /test
#5.将jre解压后配置环境变量
ENV JAVA_HOME=/test/jre1.8.0_391
ENV CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV PATH=$JAVA_HOME/bin:$PATH
#6.容器启动时,需要执行的命令(执行jar包)
CMD java -jar spring.jar

创建镜像:

docker build -t spring:v3

再查看镜像:

docker images

运行:

docker run -itd spring:v3

虽然储存的减少可能很小,但是当需要量上来是时候也是节省了大量的储存空间的。

Ⅲ. 完善镜像

需要将储存控制到很少可以使用这个镜像jeanblanchard/alpine-glibc,这个镜像所需的储存很少,而通过这个镜像自定义出来的镜像也会少很多。

首先需要下载这个镜像:

docker pull jeanblanchard/alpine-glibc

再查看镜像的信息:

docker images

可以看到所需的储存空间很少。

然后我们将指定的镜像修改为这个镜像将Dockerfile文件,再次镜像编辑为以下内容。

#1.指定基础镜像,并且必须是第一条指令
FROM  jeanblanchard/alpine-glibc
#2.指明该镜像的作者和其电子邮件
MAINTAINER  CloudJun  "jun737x@163.com"
#3.在构建镜像时,指定镜像的工作目录,之后的命令都是基于此工作目录,如果不存在,则会创建目录
WORKDIR  /test
#4.将文件从Docker主机jre包复制到Docker镜像中,自动将jdk的压缩包进行解压
COPY  spring.jar /test
ADD  jre-8u391-linux-x64.tar.gz  /test
#5.将jre解压后配置环境变量
ENV JAVA_HOME=/test/jre1.8.0_391
ENV CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV PATH=$JAVA_HOME/bin:$PATH
#6.容器启动时,需要执行的命令(执行jar包)
CMD java -jar spring.jar

创建镜像:

docker build -t spring:v4

再查看镜像:

docker images

现在这样的需要的储存空间就相对少了一半,更加的节省了资源空间。

现在映射端口运行:

docker run -itd --name s1 -p 8080:8080 spring:v4

之后在主机浏览器中访问虚拟机IP的访问路径:IP地址:8080 

四、镜像上传仓库

首先需要在我们的阿里云账号中开启镜像仓库,点击用户左边的控制器,点击容器镜像服务ACR,点击实例列表,在其中点击创建个人版本的,企业版要米,创建后需要设置密码。

容器镜像服务 (aliyun.com)

之后将以上的登入凭证复制粘贴到虚拟机中执行命令,前面的$不用复制进去,之后会镜像密码的输入,是自己设置的容器镜像服务密码,以下说明登入成功:

创建仓库:在实例列表中点击命名空间——>之后创建命名空间即可

如图:

之后创建一个仓库,仓库名称可以自己取

有其中的之后也可以绑定到账号中去,这里没有就可以选择本地仓库 

之后将需要上传推送到仓库的镜像取个别名,在将这个镜像绑定为阿里云的仓库,阿里云仓库在镜像仓库的第三部的将镜像推送到Registry中有命令。

第一个命令为登入,第二个命令为绑定阿里云仓库,第三个命令为上传推送到仓库

现在我们将虚拟机中共的镜像删除,删除后可以在次重阿里仓库中拉取下来。

删除:

docker rmi

镜像名:v1   (v1版本号)

拉取下载命令:

docker pull

仓库中的创建名称:v1    

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

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

相关文章

【漏洞攻击之文件上传条件竞争】

漏洞攻击之文件上传条件竞争 wzsc_文件上传漏洞现象与分析思路编写攻击脚本和重放措施中国蚁剑拿flag wzsc_文件上传 漏洞现象与分析 只有一个upload前端标签元素&#xff0c;并且上传任意文件都会跳转到upload.php页面&#xff0c;判定是一个apache容器&#xff0c;开始扫描…

龙年-微信定制红包封面,送一波

龙年新年马上就要来临了&#xff0c;我定制两款红包封面&#xff0c;送给大家。这次是借助AI的能力&#xff0c;自己独立完成&#xff0c;这大概就是这波AI浪潮的魅力&#xff0c;人人皆可参与。 另外&#xff0c;微信平台也给我推送了自己的公众号创作回顾&#xff0c;没想到居…

Failed at the node sass@4.14.1 postinstall script.

首先&#xff0c;查看node和 npm版本 #用于列出已安装的 Node.js 版本。 nvm ls #切换node版本 nvm use 12.17.0 #换国内镜像源&#xff1a;&#xff08;单独设置sass的安装源。&#xff09; npm config set sass_binary_sitehttps://npm.taobao.org/mirrors/node-sass …

小白数学建模 Mathtype 7.7傻瓜式下载安装嵌入Word/WPS以及深度使用教程

数学建模Mathtype的下载安装嵌入Word/WPS以及深度使用教程 一 Mathtype 的下载安装1.1 安装前须知1.2 下载压缩包1.3 安装注册 二 嵌入Word/WPS2.1 嵌入Word2.1.1 加载项嵌入 Word2.1.2 宏录制嵌入 Word 2.2 嵌入 WPS2.2.1 加载项嵌入 WPS2.2.2 宏录制嵌入 WPS 2.3 嵌入时报错解…

AWS 专题学习 P5 (Classic SA、S3)

文章目录 Classic Solutions Architecture无状态 Web 应用程序&#xff1a;WhatIsTheTime.com背景 & 目标架构演进Well-Architected 5 pillars 有状态的 Web 应用程序&#xff1a;MyClothes.com背景 & 目标架构演进总结 有状态的 Web 应用程序&#xff1a;MyWordPress.…

经典数据库练习题及答案

数据表介绍 --1.学生表 Student(SId,Sname,Sage,Ssex) --SId 学生编号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别 --2.课程表 Course(CId,Cname,TId) --CId 课程编号,Cname 课程名称,TId 教师编号 --3.教师表 Teacher(TId,Tname) --TId 教师编号,Tname 教师姓名 --4.成绩…

【EI会议征稿通知】第七届先进电子材料、计算机与软件工程国际学术会议(AEMCSE 2024)

第七届先进电子材料、计算机与软件工程国际学术会议(AEMCSE 2024&#xff09; 2024 7th International Conference on Advanced Electronic Materials, Computers and Software Engineering 第七届先进电子材料、计算机与软件工程国际学术会议(AEMCSE 2024)将于2024年5月10-1…

Ubuntu18.04在线镜像仓库配置

在线镜像仓库 1、查操作系统版本 rootubuntu:~# lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 18.04.5 LTS Release: 18.04 Codename: bionic 2、原文件备份 sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak 3、查…

汽车连接器接线端子和多芯线束连接界面

冷压接的开式压接和闭式压接以及热压接的超声波焊接对汽车连接器接线端子和多芯线束连接界面 连接器接线端子和多芯线束的连接是电子线束行业&#xff0c;特别是汽车行业常用的导线连接方式。汽车整车线束又由许多分支线束组成&#xff0c;而分支线束必须通过连接器实现连接&am…

医学图像的图像处理、分割、分类和定位-1

一、说明 本报告全面探讨了应用于医学图像的图像处理和分类技术。开展了四项不同的任务来展示这些方法的多功能性和有效性。任务 1 涉及读取、写入和显示 PNG、JPG 和 DICOM 图像。任务 2 涉及基于定向变化的多类图像分类。此外&#xff0c;我们在任务 3 中包括了胸部 X 光图像…

web前端项目-中国象棋【附源码】

中国象棋 【中国象棋】是一款历史悠久、深受人们喜爱的策略类游戏。在Web前端技术中&#xff0c;我们可以使用HTML、CSS和JavaScript等语言来制作一款中国象棋游戏。玩家使用棋子&#xff08;帅/相/士/炮/马/车/炮/卒&#xff09;在棋盘上相互对弈&#xff0c;将对手的“帅”棋…

GIS复试Tips(特别是南师大)

注&#xff1a;本文仅个人观点&#xff0c;仅供参考 在这提前㊗️24年考南师大GISer成功上岸&#xff01; 当然&#xff0c;考研是个考试&#xff0c;总有人顺利上岸&#xff0c;稳上岸或逆袭上岸&#xff0c;但可能也有人被刷&#xff0c;这是常态。 所以&#xff0c;㊗️你…

Linux网络编程(二-套接字)

目录 一、背景知识 1.1 端口号 1.2 网络字节序 1.3 地址转换函数 二、Socket简介 三、套接字相关的函数 3.1 socket() 3.2 bind() 3.3 connect() 3.4 listen() 3.5 accept() 3.6 read()/recv()/recvfrom() 3.7 send()/sendto() 3.8 close() 四、UPD客服/服务端实…

我用 ChatGPT 做了一次探索性数据分析,真的太太太实用了!

ChatGPT 经过短短1年时间的发展&#xff0c;其功能越来越强&#xff0c;现在已经是大多数企业和个人不可或缺的助手。特别是最新的 GPT-4 版本&#xff0c;专门在左边菜单栏给出了两个工具&#xff08;一个是数据分析&#xff0c;另一个是根据文字描述生成图片&#xff09;&…

1.12号网络

1 网络发展历史 1.1 APRAnet阶段 阿帕网&#xff0c;是Interne的最早雏形 不能互联不同类型的计算机和不同类型的操作系统 没有纠错功能 1.2 TCP/IP两个协议阶段 什么是协议 在计算机网络中&#xff0c;要做到有条不紊的交换数据&#xff0c;需要遵循一些事先约定好的规则…

(2023版)斯坦福CS231n学习笔记:DL与CV教程 (12) | 视觉模型可视化与可解释性(Visualizing and Understanding)

前言 &#x1f4da; 笔记专栏&#xff1a;斯坦福CS231N&#xff1a;面向视觉识别的卷积神经网络&#xff08;23&#xff09;&#x1f517; 课程链接&#xff1a;https://www.bilibili.com/video/BV1xV411R7i5&#x1f4bb; CS231n: 深度学习计算机视觉&#xff08;2017&#xf…

Xline v0.6.1: 一个用于元数据管理的分布式KV存储

Xline是什么&#xff1f;我们为什么要做Xline&#xff1f; Xline是一个基于Curp协议的&#xff0c;用于管理元数据的分布式KV存储。现有的分布式KV存储大多采用Raft共识协议&#xff0c;需要两次RTT才能完成一次请求。当部署在单个数据中心时&#xff0c;节点之间的延迟较低&a…

将AI的潜能转化为人类的福祉

在这个技术迅速发展的时代&#xff0c;AI不仅是一项突破性的技术&#xff0c;更是人类未来的关键。作为一名AI训练师&#xff0c;我的目标不仅仅是开发先进的AI产品&#xff0c;更重要的是让这些产品服务于人类&#xff0c;改善人们的生活。 我相信&#xff0c;AI的真正价值在于…

1月下半笔记(个人向)

最近才开始看d2l&#xff08;这种东西早该在两年前看的&#xff0c;拖到现在了&#xff09; 为了做项目还得学一手OpenGL&#xff08;被windows安装GLFW逼疯了&#xff09; 1.15 打完ICPC EC final回来&#xff0c;也许可以出一篇博客写下简单的题解。 对蛋白质相似空间子结…

Liunx:线程控制

目录 创建线程&#xff1a;pthread_create(); 线程等待&#xff1a;pthread_join(); 线程退出&#xff1a;pthread_exit(); 线程取消&#xff1a;pthread_cancel() 说线程的时候说过&#xff0c;liunx没有选择单独定义线程的数据结构和适配算法&#xff0c;而是用轻量级进程…