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來聲明,並使用{ }來界定命名空間的作用域。命名空間可以是全局的,也可以位於另一命名空間之中;但不能在類和代碼塊之中。按照是否有名字,可分爲有名字的命名空間與無名命名空間。可以多次聲明和定義同一命名空間,每次給這一命名空間添加新成員。編譯器自動合併這些同名的命名空間。
簡單示例:
二、linux中的namespaces機制:
Linux Namespace是Linux提供的一種OS-level virtualization的方法。目前在Linux系統上實現OS-level virtualization的系統有Linux VServer、OpenVZ、LXC Linux Container、Virtuozzo等,其中Virtuozzo是OpenVZ的商業版本。以上種種本質來說都是使用了Linux Namespace來進行隔離。
每個進程的命名空間都抽象成一個nsproxy指針,共享同一個命名空間的進程指向同一個指針,指針的結構通過引用計數(count)來確定使用者數目。目前Linux系統實現的命名空間子繫有UTS、IPC、MNT、PID以及NET網絡子模塊。
在Linux/include/linux/sched.h中struct 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系統命名空間的UTS、IPC、MNT、PID以及NET網絡子模塊相關定義分別在一下文件中:在Linux/include/linux/utsname.h、Linux/include/linux/ipc_namespace.h、Linux/include/linux/mnt_namespace.h、Linux/include/linux/pid_namespace.h、Linux/include/net/net_namespace.h。
三、下面簡單分析linux中PID命名空間(namespace)
linux通過命名空間管理進程pid,對於同一進程(同一個task_struct),在不同的命名空間中,看到的pid號不相同,每個pid命名空間有一套自己的pid管理方法,所以在不同的命名空間中調用getpid(),看到的pid號是不同的。
PID是命名空間中較爲複雜的模塊,因爲PID命名空間是有層次的,在高層次命名空間能看到低命名空間信息,反之不行。
pid namespace原理:
PID層次化命名空間結構圖:
註解:進程在不同命名空間有不同的數據表示,獲取一個進程信息進程號和空間信息才能唯一確定一個進程。
在Linux/include/linux/pid_namespace.h:
註釋:
child_reaper指向的進程相當於全局命名空間的init進程,其中一個重要目的是對孤兒進程進行回收;
level記錄該pid namespace的深度;
*parent記錄父pid namespace。
註釋:
nr表示命名空間中的標示;
*ns表示命名空間;
即在*ns命名空間的pid是nr;
pid_chain系統所有的upid通過pid_chain掛在同一個全局鏈表裏;
count表示應用次數;
level表示這個pid深度;
tasks表示一個pid可能對應多個task_struct;
numbers表示一個task_struct在每一個namespace的id,number[0]表示最頂層的namespace,level = 0,number[1]表示level =1。
PID命名空間在進程中的整體位置:
簡單示例:
示例結果:
由以上結構可以看到PID命名空間的層次化結構。
注:關於linux的namespace機制只瞭解皮毛,還有很多東西需要繼續學習。