1. 程式人生 > >Linux下的“句柄”(文件句柄,窗口句柄)

Linux下的“句柄”(文件句柄,窗口句柄)

32位 系統 xorg clu bsp object c 技術分享 fir some

在windows中,句柄是一個32位的整數,是內存中維護的一個對象的地址列表的整數索引,這些對象包括:窗口(window)、塊(module)、任務(task)、實例 (instance)、文件(file)、內存塊(block of memory)、菜單(menu)、控制(control)、字體(font)、資源(resource),包括圖標(icon),光標 (cursor),字符串(string)等、GDI對象(GDI object),包括位圖(bitmap),畫刷(brush),元文件(metafile),調色板(palette),畫筆(pen),區域(region),以及設備描述表(device context)。

在Linux中,每一個進程都由task_struct 數據結構來定義,即PCB,進程通過PCB中的文件描述符表找到文件描述符fd所指向的文件指針filp,文件描述符表是一個指針數組,每一個元素都指向一個內核的打開文件對象,而fd,就是這個表的下標。當用戶打開一個文件時,內核會在內部生成一個打開文件對象,並在這個表裏找到一個空項,讓這一項指向生成的打開文件對象,並返回這一項的下標作為fd,Linux中的文件描述符類似於Windows下文件句柄的概念,但區別是Windows的文件句柄是一個全局的概念,而Linux下文件句柄的作用域只在本進程空間,其中0(標準輸入)、1(標準輸出)、2(標準錯誤)是每一個進程中相同的文件描述符,由操作系統規定好,文件描述符所指向元素的文件指針為struct file結構體,在系統中是一個全局的指針。

技術分享圖片

在linux的X Window桌面環境下,Window 類似於Windows下的窗口句柄,X11/X.h中定義如下:

typedef unsigned long int XID;
typedef XID Window;
typedef XID Font;
typedef XID Pixmap;
typedef XID Drawable;
typedef XID Cursor;
typedef XID Colormap;
typedef XID GContext;
typedef XID KeySym;

同時,X的官方解釋(參考https://www.x.org/wiki/guide/concepts/#index10h4)如下:

XIDs

Many resources managed by the server are assigned a 32-bit identification number, called an XID, from a server-wide namespace. Each client is assigned a range of identifiers when it first connects to the X server, and whenever it sends a request to create a new Window, Pixmap, Cursor or other XID-labeled resource, the client (usually transparently in Xlib or xcb libraries) picks an unused XID from it‘s range and includes it in the request to the server to identify the object created by this request. This allows further requests operating on the new resource to be sent to the server without having to wait for it to process the creation request and return an identifier assignment. Since the namespace is global to the Xserver, clients can reference XID‘s from other clients in some contexts, such as moving a window belonging to another client.

大概意思是:

X Server通過一個32比特的標識號標識資源。每一個客戶端在第一次連接到X Server時,會被賦值一個標識範圍,無論是向X Server請求創建一個Window、Pixmap、或者其他XID標記的資源,客戶端(通常對於Xlib或xcb庫來說是透明的)從此範圍選擇一個未使用的XID,同時在向X Server發送請求時包含此XID以識別此次請求創建的資源。這種方式允許同時向X Server請求多個新的資源,而不需要等待每次資源創建成功並返回XID。因為對於X Server來說,域名是全局的,所以在同一個上下文中,不同的客戶端之間可以相互引用XID,例如在一個客戶端中移動屬於另一個客戶端的窗口。

在Xorg中,客戶端資源(包括XID)使用一個數組保存(dix/resource.c):

static ClientResourceRec clientTable[MAXCLIENTS];

當客戶端向X Server請求資源時,會查詢數組中相關的資源。

Linux下的“句柄”(文件句柄,窗口句柄)