首页 > 代码库 > c++ namespace和linux namespace

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

简单示例:

wKiom1QVmZLzqEkCAANAxoLnoCw521.jpg

wKioL1QVmaainDRkAALEX16FSQU627.jpg

示例结果:

 wKioL1QVmb2wewcaAAFVTl3UZs0902.jpg

 

注:关于linuxnamespace机制只了解皮毛,还有很多东西需要继续学习。


c++ namespace和linux namespace