主頁 > 後端開發 > Docker 大勢已去,Podman 即將崛起……

Docker 大勢已去,Podman 即將崛起……

2022-04-29 06:23:59 後端開發

來源:https://blog.csdn.net/qq_48289488/article/details/121905018

Podman 簡介

什么是Podman?

Podman 是一個開源的容器運行時專案,可在大多數 Linux 平臺上使用,Podman 提供與 Docker 非常相似的功能,正如前面提到的那樣,它不需要在你的系統上運行任何守護行程,并且它也可以在沒有 root 權限的情況下運行,

Podman 可以管理和運行任何符合 OCI(Open Container Initiative)規范的容器和容器鏡像,Podman 提供了一個與 Docker 兼容的命令列前端來管理 Docker 鏡像,

Podman 官網地址:https://podman.io/

Podman和Docker的主要區別是什么?
  • dockers在實作CRI的時候,它需要一個守護行程,其次需要以root運行,因此這也帶來了安全隱患,
  • podman不需要守護程式,也不需要root用戶運行,從邏輯架構上,比docker更加合理,
  • 在docker的運行體系中,需要多個daemon才能呼叫到OCI的實作RunC,
  • 在容器管理的鏈路中,Docker Engine的實作就是dockerd
  • daemon,它在linux中需要以root運行,dockerd呼叫containerd,containerd呼叫containerd-shim,然后才能呼叫runC,顧名思義shim起的作用也就是“墊片”,避免父行程退出影響容器的運訓
  • podman直接呼叫OCI,runtime(runC),通過common作為容器行程的管理工具,但不需要dockerd這種以root身份運行的守護行程,
  • 在podman體系中,有個稱之為common的守護行程,其運行路徑通常是/usr/libexec/podman/conmon,它是各個容器行程的父行程,每個容器各有一個,common的父則通常是1號行程,podman中的common其實相當于docker體系中的containerd-shim,

圖中所體現的事情是,podman不需要守護行程,而dorker需要守護行程,在這個圖的示意中,dorcker的containerd-shim與podman的common被歸在Container一層,

Podman的使用與docker有什么區別?

podman的定位也是與docker兼容,因此在使用上面盡量靠近docker,在使用方面,可以分成兩個方面來說,一是系統構建者的角度,二是使用者的角度,

在系統構建者方面,用podman的默認軟體,與docker的區別不大,只是在行程模型、行程關系方面有所區別,如果習慣了docker幾個關聯行程的除錯方法,在podman中則需要適應,可以通過pstree命令查看行程的樹狀結構,總體來看,podman比docker要簡單,由于podman比docker少了一層daemon,因此重啟的機制也就不同了,

在使用者方面,podman與docker的命令基本兼容,都包括容器運行時(run/start/kill/ps/inspect),本地鏡像(images/rmi/build)、鏡像倉庫(login/pull/push)等幾個方面,因此podman的命令列工具與docker類似,比如構建鏡像、啟停容器等,甚至可以通過alias docker=podman可以進行替換,因此,即便使用了podman,仍然可以使用docker.io作為鏡像倉庫,這也是兼容性最關鍵的部分,

Podman 常用命令

容器
podman run           創建并啟動容器
podman start       #啟動容器
podman ps          #查看容器
podman stop        #終止容器
podman restart     #重啟容器
podman attach      #進入容器
podman exec        #進入容器
podman export      #匯出容器
podman import      #匯入容器快照
podman rm          #洗掉容器
podman logs        #查看日志
鏡像
podman search             #檢索鏡像
docke pull                #獲取鏡像
podman images             #列出鏡像
podman image Is           #列出鏡像
podman rmi                #洗掉鏡像
podman image rm           #洗掉鏡像
podman save               #匯出鏡像
podman load               #匯入鏡像
podmanfile                #定制鏡像(三個)
 podman build              #構建鏡像
    podman run              #運行鏡像
    podmanfile              #常用指令(四個)
     COPY                    #復制檔案
        ADD                     #高級復制
        CMD                     #容器啟動命令
        ENV                     #環境變數
        EXPOSE                  #暴露埠

部署 Podman

//安裝podman
[root@localhost ~]# yum -y install podman

//倉庫配置
[root@localhost ~]# vim /etc/containers/registries.conf
[registries.search]
registries = ['registry.access.redhat.com', 'registry.redhat.io', 'docker.io'] //這個是查找,從這三個地方查找,如果只留一個,則只在一個源里查找
unqualified-search-registries = ["registry.fedoraproject.org", "registry.access.redhat.com", "registry.centos.org", "docker.io"] //這里也要改為一個

[registries.insecure]
registries = [10.0.0.1]   //這里寫那些http的倉庫,比如harbor

//配置加速器
[registries.search]
registries = ['https://l9h8fu9j.mirror.aliyuncs.com','docker.io']

使用 Podman

使用 Podman 非常的簡單,Podman 的指令跟 Docker 大多數都是相同的,下面我們來看幾個常用的例子:

運行一個容器
[root@localhost ~]# podman run -d --name httpd docker.io/library/httpd
Trying to pull docker.io/library/httpd...
Getting image source signatures
Copying blob e5ae68f74026 done
Copying blob d3576f2b6317 done
Copying blob bc36ee1127ec done
Copying blob f1aa5f54b226 done
Copying blob aa379c0cedc2 done
Copying config ea28e1b82f done
Writing manifest to image destination
Storing signatures
0492e405b9ecb05e6e6be1fec0ac1a8b6ba3ff949df259b45146037b5f355035

//查看鏡像
[root@localhost ~]# podman images
REPOSITORY                  TAG      IMAGE ID       CREATED       SIZE
docker.io/library/httpd     latest   ea28e1b82f31   11 days ago   148 MB
列出運行的容器
[root@localhost ~]# podman ps
CONTAINER ID  IMAGE                             COMMAND           CREATED             STATUS                 PORTS  NAMES
0492e405b9ec  docker.io/library/httpd:latest    httpd-foreground  About a minute ago  Up About a minute ago         httpd

注意:如果在ps命令中添加-a,Podman 將顯示所有容器,

檢查正在運行的容器

您可以“檢查”正在運行的容器的元資料和有關其自身的詳細資訊,我們甚至可以使用 inspect 子命令查看分配給容器的 IP 地址,由于容器以無根模式運行,因此未分配 IP 地址,并且該值將在檢查的輸出中列為“無”,

[root@localhost ~]# podman inspect -l | grep IPAddress\":
            "SecondaryIPAddresses": null,
            "IPAddress": "10.88.0.5",

[root@localhost ~]# curl 10.88.0.5
<html><body><h1>It works!</h1></body></html>

注意:-l 是最新容器的便利引數,您還可以使用容器的 ID 代替 -l,

查看一個運行中容器的日志
選項
 --latest  #最近的

[root@localhost ~]# podman logs --latest
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.88.0.5. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.88.0.5. Set the 'ServerName' directive globally to suppress this message
[Mon Dec 13 15:17:53.690844 2021] [mpm_event:notice] [pid 1:tid 140665160166720] AH00489: Apache/2.4.51 (Unix) configured -- resuming normal operations
[Mon Dec 13 15:17:53.690946 2021] [core:notice] [pid 1:tid 140665160166720] AH00094: Command line: 'httpd -D FOREGROUND'
10.88.0.1 - - [13/Dec/2021:15:19:48 +0000] "GET / HTTP/1.1" 200 45
10.88.0.1 - - [13/Dec/2021:15:20:47 +0000] "GET / HTTP/1.1" 200 45
查看一個運行容器中的行程資源使用情況

可以使用top觀察容器中的 nginx pid

語法:

 podman top <container_id>
[root@localhost ~]# podman top httpd
USER       PID   PPID   %CPU    ELAPSED            TTY   TIME   COMMAND
root       1     0      0.000   15m38.599711321s   ?     0s     httpd -DFOREGROUND
www-data   7     1      0.000   15m38.599783256s   ?     0s     httpd -DFOREGROUND
www-data   8     1      0.000   15m38.599845342s   ?     0s     httpd -DFOREGROUND
www-data   9     1      0.000   15m38.599880444s   ?     0s     httpd -DFOREGROUND
停止一個運行中的容器
[root@localhost ~]# podman stop --latest
2f3edf712621d3a41e03fa8c7f6a5cdba56fbbad43a7a59ede26cc88f31006c4
[root@localhost ~]# podman ps
CONTAINER ID  IMAGE  COMMAND  CREATED  STATUS  PORTS  NAMES
洗掉一個容器
[root@localhost ~]# podman rm --latest
2f3edf712621d3a41e03fa8c7f6a5cdba56fbbad43a7a59ede26cc88f31006c4
[root@localhost ~]# podman ps -a
CONTAINER ID  IMAGE  COMMAND  CREATED  STATUS  PORTS  NAMES

以上這些特性基本上都和 Docker 一樣,Podman 除了兼容這些特性外,還支持了一些新的特性,

上傳鏡像

例如,如果我們想在 docker.io 上分享我們新建的 Nginx 容器鏡像,這很容易,首先登錄碼頭:

[root@localhost nginx]# tree
.
├── Dockerfile
└── files
    └── nginx-1.20.1.tar.gz

[root@localhost nginx]# cat Dockerfile
FROM docker.io/library/centos

ENV PATH /usr/local/nginx/sbin:$PATH
ADD files/nginx-1.20.1.tar.gz /usr/src
RUN useradd -r -M -s /sbin/nologin nginx && \
    yum -y install pcre-devel openssl openssl-devel gd-devel gcc gcc-c++ make && \
    mkdir -p /var/log/nginx && \
    cd /usr/src/nginx-1.20.1 && \
    ./configure \
    --prefix=/usr/local/nginx \
    --user=nginx \
    --group=nginx \
    --with-debug \
    --with-http_ssl_module \
    --with-http_realip_module \
    --with-http_image_filter_module \
    --with-http_gunzip_module \
    --with-http_gzip_static_module \
    --with-http_stub_status_module \
    --http-log-path=/var/log/nginx/access.log \
    --error-log-path=/var/log/nginx/error.log && \
  make && make install

CMD ["nginx","-g","daemon off"]
[root@localhost nginx]# podman build -t nginx .
// 修改鏡像名
 [root@localhost ~]# podman tag docker.io/library/nginx:latest docker.io/1314444/test:latest

// 登錄并上傳鏡像
[root@localhost ~]# podman login docker.io // 需要告訴其要登錄到docker倉庫
[root@localhost ~]# podman login docker.io
Username: 1314444  #賬戶
Password: ********  #密碼
Login Succeeded!

[root@localhost nginx]# podman push docker.io/1314444/test:latest  //上傳鏡像
Getting image source signatures
Copying blob 38c40d6c2c85 done
Copying blob fee76a531659 done
Copying blob c2adabaecedb done
Copying config 7f3589c0b8 done
Writing manifest to image destination
Copying config 7f3589c0b8 done
Writing manifest to image destination
Storing signatures

//請注意,我們將四層推送到我們的注冊表,現在可供其他人共享,快速瀏覽一下:
[root@localhost ~]# podman inspect 1314444/test:nginx
//輸出:
[
    {
        "Id": "7f3589c0b8849a9e1ff52ceb0fcea2390e2731db9d1a7358c2f5fad216a48263",
        "Digest": "sha256:7822b5ba4c2eaabdd0ff3812277cfafa8a25527d1e234be028ed381a43ad5498",
        "RepoTags": [
            "docker.io/1314444/test:nginx",
  ......

總而言之,Podman 使查找、運行、構建和共享容器變得容易

配置別名

如果習慣了使用 Docker 命令,可以直接給 Podman 配置一個別名來實作無縫轉移,你只需要在 .bashrc 下加入以下行內容即可:

[root@localhost ~]# echo "alias docker=podman" >> .bashrc
source .bashrc
[root@localhost ~]# alias
alias cp='cp -i'
alias docker='podman'
.......
用戶操作

在允許沒有root特權的用戶運行Podman之前,管理員必須安裝或構建Podman并完成以下配置,

cgroup V2Linux內核功能允許用戶限制普通用戶容器可以使用的資源,如果使用cgroupV2啟用了運行Podman的Linux發行版,則可能需要更改默認的OCI運行時,某些較舊的版本runc不適用于cgroupV2,必須切換到備用OCI運行時crun,

[root@localhost ~]# yum -y install crun     //centos8系統自帶

[root@localhost ~]# vi /usr/share/containers/containers.conf
    446 # Default OCI runtime
    447 #
    448 runtime = "crun"      //取消注釋并將runc改為crun

[root@localhost ~]# podman run -d --name web -p 80:80 docker.io/library/nginx
c8664d2e43c872e1e5219f82d41f63048ed3a5ed4fb6259c225a14d6c243677f

[root@localhost ~]# podman inspect web | grep crun
        "OCIRuntime": "crun",
            "crun",
安裝slirp4netns和fuse-overlayfs

在普通用戶環境中使用Podman時,建議使用fuse-overlayfs而不是VFS檔案系統,至少需要版本0.7.6,現在新版本默認就是了,

[root@localhost ~]# yum -y install slirp4netns

[root@localhost ~]# yum -y install fuse-overlayfs
[root@localhost ~]# vi /etc/containers/storage.conf
77 mount_program = "/usr/bin/fuse-overlayfs"     //取消注釋
/etc/subuid和/etc/subgid配置

Podman要求運行它的用戶在/etc/subuid/etc/subgid檔案中列出一系列UID,shadow-utils或newuid包提供這些檔案

[root@localhost ~]# yum -y install shadow-utils

可以在/etc/subuid和/etc/subgid查看,每個用戶的值必須唯一且沒有任何重疊,

[root@localhost ~]# useradd zz
[root@localhost ~]# cat /etc/subuid
zz:100000:65536
[root@localhost ~]# cat /etc/subgid
zz:100000:65536

// 啟動非特權ping
[root@localhost ~]# sysctl -w "net.ipv4.ping_group_range=0 200000" //大于100000這個就表示tom可以操作podman
net.ipv4.ping_group_range = 0 200000

這個檔案的格式是 USERNAME:UID:RANGE

  • 中/etc/passwd或輸出中列出的用戶名getpwent,
  • 為用戶分配的初始 UID,
  • 為用戶分配的 UID 范圍的大小,

該usermod程式可用于為用戶分配 UID 和 GID,而不是直接更新檔案,

[root@localhost ~]# usermod --add-subuids 200000-201000 --add-subgids 200000-201000 hh
grep hh /etc/subuid /etc/subgid
/etc/subuid:hh:200000:1001
/etc/subgid:hh:200000:1001
用戶組態檔

三個主要的組態檔是container.conf、storage.confregistries.conf,用戶可以根據需要修改這些檔案,

  • container.conf
// 用戶組態檔
[root@localhost ~]# cat /usr/share/containers/containers.conf
[root@localhost ~]# cat /etc/containers/containers.conf
[root@localhost ~]# cat ~/.config/containers/containers.conf  //優先級最高

如果它們以該順序存在,每個檔案都可以覆寫特定欄位的前一個檔案,

  • 配置storage.conf檔案
1./etc/containers/storage.conf
2.$HOME/.config/containers/storage.conf

在普通用戶中/etc/containers/storage.conf的一些欄位將被忽略

[root@localhost ~]#  vi /etc/containers/storage.conf
[storage]

# Default Storage Driver, Must be set for proper operation.
driver = "overlay"  #此處改為overlay
.......
mount_program = "/usr/bin/fuse-overlayfs"  #取消注釋

[root@localhost ~]# sysctl user.max_user_namespaces=15000  #如果版本為8以下,則需要做以下操作:

在普通用戶中這些欄位默認

graphroot="$HOME/.local/share/containers/storage"
runroot="$XDG_RUNTIME_DIR/containers"
  • registries.conf

配置按此順序讀入,這些檔案不是默認創建的,可以從/usr/share/containers或復制檔案/etc/containers并進行修改,

1./etc/containers/registries.conf
2./etc/containers/registries.d/*
3.HOME/.config/containers/registries.conf
授權檔案

此檔案里面寫了docker賬號的密碼,以加密方式顯示

[root@localhost ~]# podman login
Username: 1314444
Password:
Login Succeeded!
[root@localhost ~]# cat /run/user/0/containers/auth.json
{
        "auths": {
                "registry.fedoraproject.org": {
                        "auth": "MTMxNDQ0NDpIMjAxNy0xOA=="
                }
        }
}

普通用戶是無法看見root用戶的鏡像的

//root用戶
[root@localhost ~]# podman images
REPOSITORY                  TAG      IMAGE ID       CREATED       SIZE
docker.io/library/httpd     latest   ea28e1b82f31   11 days ago   146 MB

//普通用戶
[root@localhost ~]# su - zz
[zz@localhost ~]$ podman images
REPOSITORY  TAG         IMAGE ID    CREATED     SIZE

  • 容器與root用戶一起運行,則root容器中的用戶實際上就是主機上的用戶,
  • UID GID是在/etc/subuid和/etc/subgid等中用戶映射中指定的第一個UID GID,
  • 如果普通用戶的身份從主機目錄掛載到容器中,并在該目錄中以根用戶身份創建檔案,則會看到它實際上是你的用戶在主機上擁有的,
使用卷
[root@localhost ~]# su - zz
[zz@localhost ~]$ pwd
/home/zz
[zz@localhost ~]$ mkdir /home/zz/data

[zz@localhost ~]$ podman run -it -v "$(pwd)"/data:/data docker.io/library/busybox /bin/sh
Trying to pull docker.io/library/busybox:latest...
Getting image source signatures
Copying blob 3cb635b06aa2 done
Copying config ffe9d497c3 done
Writing manifest to image destination
Storing signatures
/ # ls
bin   data  dev   etc   home  proc  root  run   sys   tmp   usr   var
/ # cd data/
/data # ls
/data # touch 123
/data # ls -l
total 0
-rw-r--r--    1 root     root             0 Dec 13 00:17 123
在主機上查看
[zz@localhost ~]$ ll data/
總用量 0
-rw-r--r-- 1 zz zz 0 12月 13 00:17 123

//寫入檔案
[zz@localhost ~]$ echo "hell world" >> 123
[zz@localhost ~]$ cat 123
hell world
容器里查看
/data # cat 123
hell world

//我們可以發現在容器里面的檔案的屬主和屬組都屬于root,那么如何才能讓其屬于tom用戶呢?下面告訴你答案
/data # ls -l
total 4
-rw-rw-r--    1 root     root            12 Dec 13 00:20 123

//只要在運行容器的時候加上一個--userns=keep-id即可,
[zz@localhost ~]$ podman run -it --name test -v "$(pwd)"/data:/data --userns=keep-id docker.io/library/busybox /bin/sh
~ $ cd data/
/data $ ls -l
total 4
-rw-r--r--    1 zz       zz              11 Dec 13 00:21 123

使用普通用戶映射容器埠時會報“ permission denied”的錯誤

[zz@localhost ~]$ podman run  -d -p 80:80 httpd
Error: rootlessport cannot expose privileged port 80, you can add 'net.ipv4.ip_unprivileged_port_start=80' to /etc/sysctl.conf (currently 1024), or choose a larger port number (>= 1024): listen tcp 0.0.0.0:80: bind: permission denied

普通用戶可以映射>= 1024的埠

[zz@localhost ~]$ podman run  -d -p 1024:80 httpd
58613a6bdc70d4d4f9f624583f795a62a610596d166f0873bdff8fb26aa15092
[zz@localhost ~]$ ss -anlt
State       Recv-Q      Send-Q           Local Address:Port           Peer Address:Port      Process
LISTEN      0           128                    0.0.0.0:22                  0.0.0.0:*
LISTEN      0           128                          *:1024                      *:*
LISTEN      0           128                       [::]:22                     [::]:*

配置echo ‘net.ipv4.ip_unprivileged_port_start=80’ >> /etc/sysctl.conf后可以映射大于等于80的埠

[root@localhost ~]# echo  'net.ipv4.ip_unprivileged_port_start=80'  >> /etc/sysctl.conf
[root@localhost ~]# sysctl -p
net.ipv4.ip_unprivileged_port_start = 80

[zz@localhost ~]$ podman run -d -p 80:80 httpd
1215455a0c300d78e7bf6afaefc9873f818c6b0f26affeee4e2bc17954e72d8e
[zz@localhost ~]$ ss -anlt
State       Recv-Q      Send-Q           Local Address:Port           Peer Address:Port      Process
LISTEN      0           128                    0.0.0.0:22                  0.0.0.0:*
LISTEN      0           128                          *:1024                      *:*
LISTEN      0           128                          *:80                        *:*
LISTEN      0           128                       [::]:22                     [::]:*

近期熱文推薦:

1.1,000+ 道 Java面試題及答案整理(2022最新版)

2.勁爆!Java 協程要來了,,,

3.Spring Boot 2.x 教程,太全了!

4.別再寫滿屏的爆爆爆炸類了,試試裝飾器模式,這才是優雅的方式!!

5.《Java開發手冊(嵩山版)》最新發布,速速下載!

覺得不錯,別忘了隨手點贊+轉發哦!

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/466950.html

標籤:Java

上一篇:java實作空心金字塔

下一篇:Java Web實作用戶登錄功能

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more