c++ namespace和linux namespace

c++ namespace和linux namespace 

Namespaces命名空間


wikepedia定義:In general, a namespace is a container for a set of identifiers (also known as symbols, names).[1][2] Namespaces provide a level of direction tospecific identifiers, thus making it possible to distinguish between identifierswith the same exact name. For example, a surname could be thought ofas a namespace that makes it possible to distinguish people who have the samegiven name. In computerprogramming, namespaces are typically employed for the purpose ofgrouping symbols and identifiers around a particular functionality.


一、c++中的namespace

C++語言中,命名空間使用namespace來聲明,並使用{ }來界定命名空間的作用域。命名空間可以是全局的,也可以位於另一命名空間之中;但不能在類和代碼塊之中。按照是否有名字,可分爲有名字的命名空間與無名命名空間。可以多次聲明和定義同一命名空間,每次給這一命名空間添加新成員。編譯器自動合併這些同名的命名空間。

簡單示例:

wKioL1QVl_OSd6IgAAGaSuRL42I147.jpg

 

二、linux中的namespaces機制:

Linux NamespaceLinux提供的一種OS-level virtualization的方法。目前在Linux系統上實現OS-level virtualization的系統有Linux VServerOpenVZLXC Linux ContainerVirtuozzo等,其中VirtuozzoOpenVZ的商業版本。以上種種本質來說都是使用了Linux Namespace來進行隔離。

每個進程的命名空間都抽象成一個nsproxy指針,共享同一個命名空間的進程指向同一個指針,指針的結構通過引用計數(count)來確定使用者數目。目前Linux系統實現的命名空間子繫有UTSIPCMNTPID以及NET網絡子模塊。


Linux/include/linux/sched.hstruct task_struct中找到對應的namespace結構

struct task_struct {
...
    
struct nsproxy *nsproxy;
...
};

// nsproxy是每個進程自己的namespace結構


Linux/include/linux/nsproxy.h中找到具體的namespace結構:

struct nsproxy {
    atomic_t count;
    
struct uts_namespace *uts_ns;
    
struct ipc_namespace *ipc_ns;
    
struct mnt_namespace *mnt_ns;
    
struct pid_namespace *pid_ns;
    
struct net          *net_ns;
};
extern struct nsproxy init_nsproxy;


Linux系統命名空間的UTSIPCMNTPID以及NET網絡子模塊相關定義分別在一下文件中:在Linux/include/linux/utsname.hLinux/include/linux/ipc_namespace.hLinux/include/linux/mnt_namespace.hLinux/include/linux/pid_namespace.hLinux/include/net/net_namespace.h

 

三、下面簡單分析linux中PID命名空間(namespace)

linux通過命名空間管理進程pid,對於同一進程(同一個task_struct在不同的命名空間中,看到的pid號不相同,每個pid命名空間有一套自己的pid管理方法,所以在不同的命名空間中調用getpid(),看到的pid號是不同的。

PID是命名空間中較爲複雜的模塊,因爲PID命名空間是有層次的,在高層次命名空間能看到低命名空間信息,反之不行。


pid namespace原理:

PID層次化命名空間結構圖:

wKioL1QVmO7ynByxAAE227O5sCY859.jpg

註解:進程在不同命名空間有不同的數據表示,獲取一個進程信息進程號和空間信息才能唯一確定一個進程。

 

Linux/include/linux/pid_namespace.h

wKiom1QVmQeTnvyIAAIjDBcrxJo926.jpg

註釋:

child_reaper指向的進程相當於全局命名空間的init進程,其中一個重要目的是對孤兒進程進行回收;

level記錄該pid namespace的深度;

*parent記錄父pid namespace


Linux/include/linux/pid.h

wKiom1QVmS7jNir6AAEj9a4DpI0165.jpg

註釋:

nr表示命名空間中的標示;

*ns表示命名空間;

即在*ns命名空間的pidnr

pid_chain系統所有的upid通過pid_chain掛在同一個全局鏈表裏;

count表示應用次數;

level表示這個pid深度;

tasks表示一個pid可能對應多個task_struct

numbers表示一個task_struct在每一個namespaceid,number[0]表示最頂層的namespacelevel = 0number[1]表示level =1


PID命名空間在進程中的整體位置:

wKioL1QVmXLBfzr0AAFw84aCwSc751.jpg

簡單示例:

wKioL1QWrVqwIAI1AANdHvUQOZA170.jpg

wKioL1QWrVzTAgVWAAMeAsmyF-k413.jpg

wKiom1QWrUmhHp-9AAL4I3n4uVE946.jpg

wKioL1QWrWCAFRSdAAM-PfFVA_4655.jpg


示例結果:

 

wKiom1QWrWSBtkq8AAJ6bckyGT8377.jpg

wKiom1QWrWWD8ezOAAJFK_cC-VE290.jpg

由以上結構可以看到PID命名空間的層次化結構。

 

注:關於linuxnamespace機制只瞭解皮毛,還有很多東西需要繼續學習。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章