色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何組織PID命名空間的各種ID?PID命名空間基本概念簡析

冬至子 ? 來源:技術(shù)基本功修煉 ? 作者:郭玲 ? 2023-07-18 14:59 ? 次閱讀

Linux 支持以下命名空間類型:

  • Mount (CLONE_NEWNS;2.4.19,2002)
  • UTS (CLONE_NEWUTS; 2.6.19,2006)
  • IPC (CLONE_NEWIPC; 2.6.19,2006)
  • PID (CLONE_NEWPID; 2.6.24,2008)
  • Network(CLONE_NEWNET;2.6.29,2009)
  • User (CLONE_NEWUSER;3.8,2013)
  • Cgroup(CLONE_NEWCGROUP;4.6,2016)

命名空間 API 由三個系統(tǒng)調(diào)用(clone()、unshare()和setns())以及許多/proc文件組成。CLONE_NEW* 常量包括:

CLONE_NEWIPC,CLONE_NEWNS , CLONE_NEWNET , CLONE_NEWPID ,CLONE_NEWUSERCLONE_NEWUTS

int clone(int (*child_func)(void *), void *child_stack, int flags, void *arg);

有二十多個不同的CLONE_*標(biāo)志 控制clone()操作的各個方面,包括父進(jìn)程和子進(jìn)程是否共享資源,例如虛擬內(nèi)存、打開的文件描述符和信號配置。

如果在調(diào)用中指定了CLONE_NEW* 之一,則會創(chuàng)建相應(yīng)類型的 新命名空間 ,并且新進(jìn)程將成為該****命名空間的成員;可以在flags中指定多個 CLONE_NEW* 。

在本文中,我們將研究 clone系統(tǒng)調(diào)用的 PID 命名空間部分,以及內(nèi)核如何組織 PID 命名空間的各種ID。本文分析基于內(nèi)核版本 linux-5.15.60。

一、PID命名空間基本概念

PID命名空間隔離的全局資源是“進(jìn)程ID編號”空間。這意味著“不同PID命名空間”中的進(jìn)程可以具有“相同的進(jìn)程ID”。PID命名空間用于“在主機(jī)系統(tǒng)之間遷移的容器”,同時保持容器內(nèi)部進(jìn)程的相同進(jìn)程ID。

與傳統(tǒng)Linux(或UNIX)系統(tǒng)上的進(jìn)程一樣,在PID命名空間中的進(jìn)程ID是唯一的,并且從 PID 1開始按順序分配。同樣地,與傳統(tǒng)Linux系統(tǒng)一樣,PID 1——init進(jìn)程是特殊的:它是在命名空間內(nèi)創(chuàng)建的第一個進(jìn)程,并且在命名空間內(nèi)執(zhí)行某些管理任務(wù)。

通過調(diào)用帶有 CLONE_NEWPID 標(biāo)志的clone()函數(shù)可以“創(chuàng)建一個新的PID命名空間”。我們將展示一個簡單的示例程序,使用clone()函數(shù)創(chuàng)建一個新的PID命名空間,并使用該程序來解釋PID命名空間的一些基本概念。

主程序使用clone()函數(shù)創(chuàng)建一個新的PID命名空間,并顯示生成子進(jìn)程的PID:

child_pid = clone(childFunc,
              child_stack + STACK_SIZE,   /* Points to start of downwardly growing stack */
              CLONE_NEWPID | SIGCHLD, argv[1]);
printf("PID returned by clone(): %ldn", (long) child_pid);

新創(chuàng)建的子進(jìn)程在childFunc()中開始執(zhí)行,該函數(shù)接收clone()調(diào)用的最后一個參數(shù)(argv[1])作為它的參數(shù)。這個參數(shù)后面再解釋。childFunc()函數(shù)顯示由clone()創(chuàng)建的子進(jìn)程的進(jìn)程ID和父進(jìn)程ID,并最后執(zhí)行標(biāo)準(zhǔn)的sleep程序:

printf("childFunc(): PID = %ldn", (long) getpid());
printf("ChildFunc(): PPID = %ldn", (long) getppid()); 
   ...
execlp("sleep", "sleep", "1000", (char *) NULL);

當(dāng)我們運(yùn)行這個程序時,輸出的前幾行如下:

[root@haha demo]# ./pidns_init_sleep /proc30
PID returned by clone(): 25070
childFunc(): PID = 1
childFunc(): PPID = 0
Mounting
procfs at /proc30

前兩行輸出顯示了從兩個不同PID命名空間的角度來看子進(jìn)程的PID:調(diào)用clone()的“調(diào)用者的命名空間”和“子進(jìn)程所在的命名空間”。

換句話說,子進(jìn)程有兩個PID:在父命名空間中為 25070,在clone()調(diào)用創(chuàng)建的新PID命名空間中為1。下一行輸出顯示了子進(jìn)程在所在PID命名空間中的父進(jìn)程ID(即getppid()返回的值)。

父進(jìn)程PID為0,展示了PID命名空間操作的一個小特殊情況。

正如我們后面詳細(xì)介紹的那樣,PID命名空間形成了一個層次結(jié)構(gòu):一個進(jìn)程只能看到“自己所在的PID命名空間”和 嵌套在該P(yáng)ID命名空間下的“子命名空間中”的進(jìn)程。

由于由clone()“創(chuàng)建的子進(jìn)程的父進(jìn)程”處于不同的命名空間中,子進(jìn)程無法“看到”父進(jìn)程;因此,getppid()將父進(jìn)程PID報(bào)告為零。

要解釋pidns_init_sleep的最后一行輸出,我們需要回到一個我們在討論childFunc()函數(shù)實(shí)現(xiàn)時跳過的代碼片段。

在Linux系統(tǒng)上,每個進(jìn)程都有一個特殊的目錄路徑"/proc/PID",其中PID表示進(jìn)程的ID。這個目錄包含了描述該進(jìn)程的虛擬文件。

這個機(jī)制被稱為PID命名空間模型。在一個PID命名空間中,只有屬于該命名空間或其子命名空間的進(jìn)程的信息會顯示在對應(yīng)的"/proc/PID"目錄中。

[root@haha linux-5.15.60]# mount |grep "proc on /proc"
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
proc on /proc2 type proc (rw,relatime)
proc on /proc2 type proc (rw,relatime)
proc on /proc10 type proc (rw,relatime)
proc on /proc20 type proc (rw,relatime)
proc on /proc30 type proc (rw,relatime)
[root@haha linux-5.15.60]#

但是,要使與PID命名空間對應(yīng)的"/proc/PID"目錄可見,需要將proc文件系統(tǒng)掛載到該P(yáng)ID命名空間。我們可以在一個PID命名空間內(nèi)的shell中,運(yùn)行 mount命令來實(shí)現(xiàn):

mount -t proc proc /mount_point

另外,也可以使用mount()系統(tǒng)調(diào)用來掛載procfs,我們程序的childFunc()函數(shù)就是這樣的:

char *mount_point = arg;
  if (mount_point != NULL) {
      mkdir(mount_point, 0555);       /* Create directory for mount point */
      if (mount("proc", mount_point, "proc", 0,NULL) == -1)
          errExit("mount");
      printf("Mounting procfs at %sn", mount_point);
   }

在我們的shell會話中,在/proc上掛載的procfs將顯示父PID命名空間中可見的進(jìn)程的PID子目錄,而在/proc30 上掛載的procfs將顯示駐留在子PID命名空間中的進(jìn)程的PID子目錄。

讓我們回到運(yùn)行pidns_init_sleep的shell會話。我們停止程序并使用ps命令在父命名空間的上下文中檢查父進(jìn)程和子進(jìn)程的一些細(xì)節(jié)。

圖片

上述輸出的最后一行中的"PPID"值(25069)顯示“執(zhí)行sleep的進(jìn)程”的父進(jìn)程是執(zhí)行pidns_init_sleep的進(jìn)程。

通過使用readlink命令來顯示/proc/PID/ns/pid符號鏈接,我們可以看到這兩個進(jìn)程位于不同的PID命名空間中:

[root@haha demo]# readlink /proc/25069/ns/pid
pid:[4026531836]
[root@haha demo]# readlink /proc/25070/ns/pid
pid:[4026537948]
[root@haha demo]#

此時,我們還可以使用新掛載的procfs來獲取有關(guān)新PID命名空間中進(jìn)程的信息,從該命名空間的角度來看。首先,我們可以使用以下命令獲取該命名空間中的PID列表:

[root@haha demo]# ls -d /proc30/[1-9]*
/proc30/1

如上所示,PID命名空間只包含一個進(jìn)程,其PID(在該命名空間內(nèi))為1。我們還可以使用/proc/PID/status文件作為另一種方法,獲取關(guān)于該進(jìn)程的一些相同信息,就像我們之前在shell會話中看到的那樣:

[root@haha demo]# cat /proc30/1/status | egrep '^(Name|PP*id)'
Name: sleep
Pid:   1
PPid:  0
[root@haha
demo]#

文件中的PPid字段為0,與getppid()報(bào)告子進(jìn)程的父進(jìn)程ID為0的事實(shí)相匹配。(子命名空間看不到父命名空間的進(jìn)程)

二、嵌套的PID命名空間

如前所述,PID(進(jìn)程標(biāo)識符)命名空間以父子關(guān)系的層級嵌套方式存在。在一個PID命名空間內(nèi),可以看到同一命名空間中的所有其他進(jìn)程,以及屬于后代命名空間的所有進(jìn)程。

在這里,“看到”意味著能夠進(jìn)行基于特定PID的系統(tǒng)調(diào)用(例如,使用kill()向進(jìn)程發(fā)送信號)。子PID命名空間中的進(jìn)程無法看到僅存在于父PID命名空間(或更遠(yuǎn)的祖先命名空間)中的進(jìn)程。

一個進(jìn)程在PID命名空間層級中的每一層都會有一個PID,從其所在的PID命名空間一直到根PID命名空間。調(diào)用getpid()始終報(bào)告與進(jìn)程所在命名空間相關(guān)聯(lián)的PID。

我們可以使用這里顯示的程序(multi_pidns.c)來展示進(jìn)程在每個可見的命名空間中具有不同的PID。為簡潔起見,我們將簡單地解釋程序的功能,而不是逐行解析其代碼。

該程序以嵌套PID命名空間中的子進(jìn)程遞歸方式創(chuàng)建一系列子進(jìn)程。在調(diào)用程序時指定的命令行參數(shù)確定要創(chuàng)建多少個子進(jìn)程和PID命名空間:

./multi_pidns 5

除了創(chuàng)建一個新的子進(jìn)程,每個遞歸步驟還在一個唯一命名的掛載點(diǎn)上掛載procfs文件系統(tǒng)。在遞歸的最后,最后一個子進(jìn)程執(zhí)行了sleep程序。上述命令行輸出如下:

[root@haha demo]# ls -d /proc4/[1-9]* 
/proc4/1  /proc4/2  /proc4/3  /proc4/4  /proc4/5
[root@haha demo]# ls -d /proc3/[1-9]* 
/proc3/1  /proc3/2  /proc3/3  /proc3/4
[root@haha demo]# ls -d /proc2/[1-9]* 
/proc2/1  /proc2/2  /proc2/3
[root@haha demo]# ls -d /proc1/[1-9]* 
/proc1/1  /proc1/2
[root@haha demo]# ls -d /proc0/[1-9]* 
/proc0/1

查看每個procfs中的PID,我們可以看到每個連續(xù)的procfs "級別"包含的PID越來越少,這也表示了每個PID命名空間只顯示屬于該P(yáng)ID命名空間或其后代命名空間的進(jìn)程。

讓我們看下在所有可見的命名空間中,遞歸結(jié)束時的PID:

[root@haha demo]# grep -H 'Name:.*sleep'/proc?/[1-9]*/status
/proc0/1/status:Name:   sleep
/proc1/2/status:Name:   sleep
/proc2/3/status:Name:   sleep
/proc3/4/status:Name:   sleep
/proc4/5/status:Name:   sleep
[root@haha demo]#

換句話說,在最深層嵌套的 PID 命名空間 ( /proc0 ) 中,執(zhí)行sleep的進(jìn)程的 PID 為 1,而在創(chuàng)建的最頂層 PID 命名空間 ( /proc4 ) 中,該進(jìn)程的 PID 為 5。

三、內(nèi)核實(shí)現(xiàn)PID命名空間

要了解內(nèi)核如何組織和管理進(jìn)程ID,首先要知道進(jìn)程ID 的類型:

內(nèi)核中進(jìn)程ID 的類型用 pid_type 來描述,它定義在 includelinuxpid.h 中

enum pid_type {
  PIDTYPE_PID,
  PIDTYPE_TGID,
  PIDTYPE_PGID,
  PIDTYPE_SID,
  PIDTYPE_MAX,
};
  • PID 是內(nèi)核唯一區(qū)分每個進(jìn)程的ID。使用 fork 或 clone 系統(tǒng)調(diào)用時生成的進(jìn)程將被內(nèi)核分配一個新的唯一 PID 值。
  • TGID 是線程組ID。在一個進(jìn)程中,如果使用 clone_THREAD 標(biāo)志來調(diào)用 clone創(chuàng)建的進(jìn)程,那么它就是該進(jìn)程的一個線程(即輕量級進(jìn)程,Linux沒有嚴(yán)格的進(jìn)程概念),它們在一個線程組中。同一線程組中所有進(jìn)程都有相同的TGID,但由于是不同的進(jìn)程,所以它們的PID不同;線程的領(lǐng)導(dǎo)者(也稱為主線程)的TGID 與其 PID 相同。
  • PGID 獨(dú)立進(jìn)程可以組成進(jìn)程組(使用 setpgrp 系統(tǒng)調(diào)用),進(jìn)程組可以簡化向組內(nèi)所有進(jìn)程發(fā)送信號的操作。例如,通過管道連接的連接屬于同一個進(jìn)程組。進(jìn)程組ID 稱為 PGID。進(jìn)程組中所有的進(jìn)程都有相同的 PGID,等于組長的 PID。
  • SID 可以將多個進(jìn)程組組成一個會話組(使用 setsid 系統(tǒng)調(diào)用),可用于終端編程。會話組中所有進(jìn)程都有相同的SID,該SID 存儲在 task_struct 的 session 成員中。

PID命名空間的層級關(guān)系如下:有 4 個命名空間。父命名空間派生兩個子命名空間,其中一個子命名空間派生另一個子命名空間。

圖片

由于每個命名空間是相互隔離的,所以每個命名空間可以有一個 PID 為1的進(jìn)程。由于命名空間的層次性,父命名空間是知道子命名空間的存在的,所以子命名空間需要映射到父命名空間,

因此上圖中 第 1 級 的兩個兩個子命名空間中的 6 個進(jìn)程 都映射到 其父命名空間的 PID 號 5~ 10.

系統(tǒng)使用 struct task_struct 表示一個進(jìn)程,進(jìn)程中存儲了全局ID 和 本地ID。

全局ID ---- 內(nèi)核本身和初始命名空間中的唯一ID。 系統(tǒng)啟動時 init 進(jìn)程屬于初始命名空間。全局ID 包括 pid_t pid 和 pid_t tgid 。默認(rèn)情況下 pid_t 用 int 表示。

本地ID ---- 對于一個特定的命名空間來說,它在其命名空間中分配的ID就是本地ID。本地ID 用 struct pid * thread_pid 表示。

圖片

PID 數(shù)據(jù)結(jié)構(gòu)

成員 tasks 是一個數(shù)組,每個數(shù)組項(xiàng)是一個哈希表頭,對應(yīng)一個ID 類型,因此一個ID 可用于多個進(jìn)程(比如多個進(jìn)程的進(jìn)程組相同)。

struct upid {
  int nr;// ID 的具體值
  struct pid_namespace* ns;
};
struct pid {
  refcount_t count;// 引用數(shù), 一個PID 可能用于多個進(jìn)程
  unsigned int level;
  spinlock_t lock;
   /* lists of tasks that use this pid */
  struct hlist_head tasks[PIDTYPE_MAX];
  struct hlist_head inodes;
   /* wait queue for pidfd notifications */
  wait_queue_head_twait_pidfd;
  struct rcu_head rcu;
   struct upid numbers[1]; // 柔性數(shù)組,特定命名空間可見的信息, 數(shù)組大小為level
};

PID 命名空間結(jié)構(gòu)

struct pid_namespace {
  struct idr idr;
  struct rcu_head rcu;
  unsigned int pid_allocated; // 已分配多少個pid
  struct task_struct* child_reaper; // 指向當(dāng)前命名空間的 init 進(jìn)程,每個命名空間都有一個相當(dāng)于全局init進(jìn)程的進(jìn)程
  struct kmem_cache* pid_cachep; // 指向分配pid 的slab地址
  unsigned int level;// 當(dāng)前命名空間的級別。初始命名空間的級別為0,其子命名空間級別為1,依次遞增。
  struct pid_namespace* parent; // 指向父命名空間
#ifdefCONFIG_BSD_PROCESS_ACCT
  struct fs_pin* bacct;
#endif
  struct user_namespace* user_ns;
  struct ucounts* ucounts;
  int reboot;/* group exit code if this pidns was rebooted */
  struct ns_common ns;
} __randomize_layout;

假設(shè)一個進(jìn)程組中有A、B 兩個進(jìn)程,且進(jìn)程組組長為A,進(jìn)程A 是在 2 級命名空間中創(chuàng)建的,它的pid為45 ,映射到1級命名空間,分配給它的pid為123;然后它被映射到級別 0 的命名空間,分配給它的 pid 是 27760。

進(jìn)程A 創(chuàng)建了一個線程 A1, 那么 A, A1, B 的命名空間和進(jìn)程的關(guān)系如下圖所示:

  • 進(jìn)程 A 的成員 struct pid* thread_pid 是內(nèi)核對進(jìn)程標(biāo)識符的內(nèi)部表示方式。
  • struct pid 以哈希鏈表的方式存儲,可以通過數(shù)字pid值快速找到它和它所引用的進(jìn)程。
  • struct pid 保存了 嵌套的多個命名空間的指針 和 進(jìn)程在此命名空間的進(jìn)程標(biāo)識符 nr。
  • 命名空間使用基數(shù)樹保存當(dāng)前命名空間的 所有 struct pid,基數(shù)樹的索引就是 進(jìn)程在此命名空間的進(jìn)程標(biāo)識符。

圖片

最后有個問題:如何通過PID 快速找到 task_struct?

內(nèi)核代碼通過 find_task_by_vpid 來實(shí)現(xiàn)這個功能,其實(shí)通過上面這張圖就可以得出結(jié)論,簡單的步驟如下:

首先,通過 pid 和 命名空間nr,在基數(shù)樹上找到對應(yīng)的 struct pid;

然后,通過 pid_type 在 struct pid 找到對應(yīng)的節(jié)點(diǎn)struct hlist_node;

最后,根據(jù)內(nèi)核的 container_of 機(jī)制 和 struct hlist_node 可以找到 struct task_struct 結(jié)構(gòu)體。

struct task_struct* find_task_by_vpid(pid_t vnr) {
  return find_task_by_pid_ns(vnr,task_active_pid_ns(current));
}


struct task_struct* find_task_by_pid_ns(pid_t nr, struct pid_namespace* ns) {
  RCU_LOCKDEP_WARN(!rcu_read_lock_held(), "find_task_by_pid_ns() needs rcu_read_lock() protection");
  return pid_task(find_pid_ns(nr, ns),PIDTYPE_PID);
}


struct pid* find_pid_ns(int nr, struct pid_namespace* ns) {
  return idr_find(&ns- >idr, nr);
}


struct task_struct* pid_task(struct pid* pid, enum pid_type type) {
  struct task_struct* result = NULL;
  if (pid)
{
      structhlist_node* first;
      first = rcu_dereference_check(hlist_first_rcu(&pid- >tasks[type]),
          lockdep_tasklist_lock_is_held());
      if (first)
          result =hlist_entry(first, struct task_struct, pid_links[(type)]);
   }
  return result;
}
#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 存儲器
    +關(guān)注

    關(guān)注

    38

    文章

    7528

    瀏覽量

    164194
  • Linux系統(tǒng)
    +關(guān)注

    關(guān)注

    4

    文章

    595

    瀏覽量

    27470
  • PID控制
    +關(guān)注

    關(guān)注

    10

    文章

    460

    瀏覽量

    40201
收藏 人收藏

    評論

    相關(guān)推薦

    鴻蒙TypeScript學(xué)習(xí)第19天【命名空間

    命名空間一個最明確的目的就是解決重名問題。
    的頭像 發(fā)表于 04-17 15:43 ?1014次閱讀
    鴻蒙TypeScript學(xué)習(xí)第19天【<b class='flag-5'>命名</b><b class='flag-5'>空間</b>】

    C++筆記008:C++命名空間 namespace的作用和使用解析

    。因此引入命名空間(namespace)這個概念,專門用于解決上面的問題,就像在“A”這個名字前面加上額外的附加信息一樣(額外的附加信息…..這句是不是病句),命名
    發(fā)表于 08-11 12:30

    Linux的命名空間機(jī)制

    Linux命名空間概述
    發(fā)表于 03-18 14:40

    命名空間的實(shí)現(xiàn)

    (1) 在用fork或clone系統(tǒng)調(diào)用創(chuàng)建新進(jìn)程時,有特定的選項(xiàng)可以控制是與父進(jìn)程共享命名空間,還是建立新的命名空間。(2) unshare系統(tǒng)調(diào)用將進(jìn)程的某些部分從父進(jìn)程分離,其中
    發(fā)表于 05-24 06:21

    hbase shell創(chuàng)建命名空間

    一.hbase shell創(chuàng)建命名空間hbase shellcreate_namespace "gofish"二.python實(shí)現(xiàn)hbase增刪改查# -*- coding
    發(fā)表于 07-28 06:45

    python常規(guī)包與命名空間

    python常規(guī)包與命名空間包1. 常規(guī)包在 Python 3.3 之前或者說 Python 2 中,一個包想要被導(dǎo)入使用,那么該包內(nèi)必須要有 __init__.py 文件,這個文件是 Python
    發(fā)表于 03-11 15:46

    nvs_open和nvs_get從不存在的命名空間中工作會有何影響?

    我有一些設(shè)備在它們的 nvs 存儲中有不同的命名空間和分區(qū)來存儲不同的值,但共享相同的代碼。在我的代碼中,當(dāng)特定命名空間不存在時,我已經(jīng)做了例外處理:代碼:esp_err_t ret
    發(fā)表于 03-01 09:03

    nvs_open和nvs_get從不存在的命名空間中工作是怎么回事?

    我有一些設(shè)備在它們的 nvs 存儲中有不同的命名空間和分區(qū)來存儲不同的值,但共享相同的代碼。在我的代碼中,當(dāng)特定命名空間不存在時,我已經(jīng)做了例外處理:esp_err_t ret = n
    發(fā)表于 04-14 06:30

    模糊PID控制和空間矢量調(diào)制的通用變頻器設(shè)計(jì)

    模糊PID控制和空間矢量調(diào)制的通用變頻器設(shè)計(jì)
    發(fā)表于 04-13 15:42 ?27次下載

    集群模式_Data_ONTAP_中的命名空間

    集群模式_Data_ONTAP_中的命名空間
    發(fā)表于 12-28 11:17 ?0次下載

    C++中命名空間的幾大用法

    譯者注:可能很多程序員對C++已經(jīng)非常熟悉,但是對命名空間經(jīng)常使用到的地方還不是很明白,這篇文章就針對命名空間這一塊做了一個敘述。 命名
    發(fā)表于 09-28 18:31 ?0次下載

    基于PID調(diào)節(jié)相關(guān)的15個基本概念詳解

    PID入門讀此文,必須熟透于心的15個PID基本概念
    的頭像 發(fā)表于 01-08 09:14 ?6726次閱讀
    基于<b class='flag-5'>PID</b>調(diào)節(jié)相關(guān)的15個<b class='flag-5'>基本概念</b>詳解

    關(guān)于工業(yè)控制PID系統(tǒng)中的十五個基本概念

    PID調(diào)節(jié)系統(tǒng)PID功能由PID調(diào)節(jié)器或DCS系統(tǒng)內(nèi)部功能程序模塊實(shí)現(xiàn),了解與PID調(diào)節(jié)相關(guān)的一些基本概念,有助于
    發(fā)表于 11-13 14:21 ?1929次閱讀

    一文了解C++的命名空間

    在C++中,變量、函數(shù)和類都是大量存在的,這些變量、函數(shù)和類的名稱將都存在于全局命名空間中,會導(dǎo)致很多沖突, 使用命名空間的目的是對標(biāo)識符的名稱進(jìn)行本地化,以避免
    的頭像 發(fā)表于 06-29 14:48 ?2356次閱讀
    一文了解C++的<b class='flag-5'>命名</b><b class='flag-5'>空間</b>

    PID剛?cè)腴T?新手必看的15個PID基本概念

    PID調(diào)節(jié)系統(tǒng)PID功能由PID調(diào)節(jié)器或DCS系統(tǒng)內(nèi)部功能程序模塊實(shí)現(xiàn),了解與PID調(diào)節(jié)相關(guān)的一些基本概念,有助于
    的頭像 發(fā)表于 09-25 19:40 ?2273次閱讀
    <b class='flag-5'>PID</b>剛?cè)腴T?新手必看的15個<b class='flag-5'>PID</b><b class='flag-5'>基本概念</b>!
    主站蜘蛛池模板: 一个人在线观看视频免费 | 18动漫在线观看 | 迅雷成人论坛 | 亚洲综合中文 | 8x8x我要打机飞在线观看 | 动漫美女被羞羞动漫怪物 | RUNAWAY韩国动漫免费官网版 | 晚夜免费禁用十大亏亏 | CHINA篮球体育飞机2022网站 | 手机在线免费 | 国产精品久久久久久久久齐齐 | GAY2022空少被体育生暴菊 | 成人亚洲乱码在线 | 动漫美女搞鸡 | 四虎影院2022 | 妇少水多18P蜜泬17P亚洲乱 | 中文字幕在线不卡精品视频99 | 妻子的妹妹在线 | 亚洲黄色在线观看 | 99精品成人无码A片观看金桔 | 精品午夜视频 | 国模精品一区二区三区视频 | 么公一夜要了我一八次视频HD | 龙泽罗拉av | 久久久久婷婷国产综合青草 | 国产成人a一在线观看 | 精品日韩视频 | 浪货嗯啊趴下NP粗口黄暴 | 精品区2区3区4区产品乱码9 | 国产偷国产偷亚洲高清人乐享 | 久久福利影院 | 麻豆啊传媒app黄版破解免费 | 两个女人互添下身高潮自视频 | 午夜射精日本三级 | 久久国产露脸老熟女熟69 | 爽a中文字幕一区 | 空姐被黑人 苏晓曼 | 久久久久99精品成人片三人毛片 | 被滋润的艳妇疯狂呻吟白洁老七 | 毛片无码免费无码播放 | 国产精品亚洲精品日韩电影 |