rtt設備驅動框架學習——內核對象基類object

內核對象基類object

這個基類是內核所有對象的基類

在rt-thread/include/rtdef.h文件里有對內核對象基類object的定義

/*** Base structure of Kernel object*/
struct rt_object
{char       name[RT_NAME_MAX];                       /**< name of kernel object */rt_uint8_t type;                                    /**< type of kernel object */rt_uint8_t flag;                                    /**< flag of kernel object */#ifdef RT_USING_MODULEvoid      *module_id;                               /**< id of application module */
#endifrt_list_t  list;                                    /**< list node of kernel object */
};
typedef struct rt_object *rt_object_t;                  /**< Type for kernel objects. */

object屬性有 內核對象名字 , 內核對象類型 , 內核對象標志,還有一個鏈表節點。

內核對象信息結構體

/*** The information of the kernel object*/
struct rt_object_information
{enum rt_object_class_type type;                     /**< object class type */rt_list_t                 object_list;              /**< object list */rt_size_t                 object_size;              /**< object size */
};

其中rt_object_class_type是一個枚舉類型,定義如下

/***  The object type can be one of the follows with specific*  macros enabled:*  - Thread*  - Semaphore*  - Mutex*  - Event*  - MailBox*  - MessageQueue*  - MemHeap*  - MemPool*  - Device*  - Timer*  - Module*  - Unknown*  - Static*/
enum rt_object_class_type
{RT_Object_Class_Null          = 0x00,      /**< The object is not used. */RT_Object_Class_Thread        = 0x01,      /**< The object is a thread. */RT_Object_Class_Semaphore     = 0x02,      /**< The object is a semaphore. */RT_Object_Class_Mutex         = 0x03,      /**< The object is a mutex. */RT_Object_Class_Event         = 0x04,      /**< The object is a event. */RT_Object_Class_MailBox       = 0x05,      /**< The object is a mail box. */RT_Object_Class_MessageQueue  = 0x06,      /**< The object is a message queue. */RT_Object_Class_MemHeap       = 0x07,      /**< The object is a memory heap. */RT_Object_Class_MemPool       = 0x08,      /**< The object is a memory pool. */RT_Object_Class_Device        = 0x09,      /**< The object is a device. */RT_Object_Class_Timer         = 0x0a,      /**< The object is a timer. */RT_Object_Class_Module        = 0x0b,      /**< The object is a module. */RT_Object_Class_Memory        = 0x0c,      /**< The object is a memory. */RT_Object_Class_Unknown       = 0x0e,      /**< The object is unknown. */RT_Object_Class_Static        = 0x80       /**< The object is a static object. */
};

有我們常見的線程,信號量等等,最后一個靜態類型 就是 第一位 置1。
這里我們只關注 設備類 ,也就是 RT_Object_Class_Device

它們之間具體是個什么關系呢
具體我們來看rt-thread/src/object.c文件

對象容器

對象容器就是一個rt_object_information類型的數組,數組名_object_container,數組長度為RT_Object_Info_Unknown,這個數組中的每個值都是rt_object_information類型。

static struct rt_object_information _object_container[RT_Object_Info_Unknown] =
{/* initialize object container - thread */{RT_Object_Class_Thread, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Thread), sizeof(struct rt_thread)},
#ifdef RT_USING_SEMAPHORE/* initialize object container - semaphore */{RT_Object_Class_Semaphore, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Semaphore), sizeof(struct rt_semaphore)},
#endif
#ifdef RT_USING_MUTEX/* initialize object container - mutex */{RT_Object_Class_Mutex, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Mutex), sizeof(struct rt_mutex)},
#endif
#ifdef RT_USING_EVENT/* initialize object container - event */{RT_Object_Class_Event, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Event), sizeof(struct rt_event)},
#endif
#ifdef RT_USING_MAILBOX/* initialize object container - mailbox */{RT_Object_Class_MailBox, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_MailBox), sizeof(struct rt_mailbox)},
#endif
#ifdef RT_USING_MESSAGEQUEUE/* initialize object container - message queue */{RT_Object_Class_MessageQueue, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_MessageQueue), sizeof(struct rt_messagequeue)},
#endif
#ifdef RT_USING_MEMHEAP/* initialize object container - memory heap */{RT_Object_Class_MemHeap, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_MemHeap), sizeof(struct rt_memheap)},
#endif
#ifdef RT_USING_MEMPOOL/* initialize object container - memory pool */{RT_Object_Class_MemPool, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_MemPool), sizeof(struct rt_mempool)},
#endif
#ifdef RT_USING_DEVICE/* initialize object container - device */{RT_Object_Class_Device, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Device), sizeof(struct rt_device)},
#endif/* initialize object container - timer */{RT_Object_Class_Timer, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Timer), sizeof(struct rt_timer)},
#ifdef RT_USING_MODULE/* initialize object container - module */{RT_Object_Class_Module, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Module), sizeof(struct rt_dlmodule)},
#endif
#ifdef RT_USING_HEAP/* initialize object container - small memory */{RT_Object_Class_Memory, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Memory), sizeof(struct rt_memory)},
#endif
};

這個容器(數組)到底有多大呢,也就是RT_Object_Info_Unknown為幾呢?

還是在object.c文件中有一個枚舉類型定義rt_object_info_type我們來看一下它。

/** define object_info for the number of _object_container items.*/
enum rt_object_info_type
{RT_Object_Info_Thread = 0,                         /**< The object is a thread. */
#ifdef RT_USING_SEMAPHORERT_Object_Info_Semaphore,                          /**< The object is a semaphore. */
#endif
#ifdef RT_USING_MUTEXRT_Object_Info_Mutex,                              /**< The object is a mutex. */
#endif
#ifdef RT_USING_EVENTRT_Object_Info_Event,                              /**< The object is a event. */
#endif
#ifdef RT_USING_MAILBOXRT_Object_Info_MailBox,                            /**< The object is a mail box. */
#endif
#ifdef RT_USING_MESSAGEQUEUERT_Object_Info_MessageQueue,                       /**< The object is a message queue. */
#endif
#ifdef RT_USING_MEMHEAPRT_Object_Info_MemHeap,                            /**< The object is a memory heap */
#endif
#ifdef RT_USING_MEMPOOLRT_Object_Info_MemPool,                            /**< The object is a memory pool. */
#endif
#ifdef RT_USING_DEVICERT_Object_Info_Device,                             /**< The object is a device */
#endifRT_Object_Info_Timer,                              /**< The object is a timer. */
#ifdef RT_USING_MODULERT_Object_Info_Module,                             /**< The object is a module. */
#endif
#ifdef RT_USING_HEAPRT_Object_Info_Memory,                            /**< The object is a memory. */
#endifRT_Object_Info_Unknown,                            /**< The object is unknown. */
};

可以看到是由宏定義決定的,宏定義在rtconfig.h文件中。
在這個枚舉類型中RT_Object_Info_Thread,RT_Object_Info_Timer,RT_Object_Info_Unknown, 是必然有的。而且RT_Object_Info_Unknown放在最后一個位置。
那么我們現在定義了RT_USING_DEVICE,開啟設備類。那么這個枚舉類型中一共有四個元素,所以RT_Object_Info_Unknown = 3。
然后 對象容器的長度 就也為3 。里面分別有線程,定時器,還有設備的對象信息rt_object_information。
這個容器直接進行了初試化,每個元素的第二個成員也就是鏈表通過宏,指向本身進行初始化,也就是這個鏈表頭(哨衛)前后都指向本身。這個鏈表用來鏈接同類的對象,后面會學習到。

#define _OBJ_CONTAINER_LIST_INIT(c)     \{&(_object_container[c].object_list), &(_object_container[c].object_list)}

內核對象函數

rt_object_get_information

/*** @brief This function will return the specified type of object information.** @param type is the type of object, which can be*             RT_Object_Class_Thread/Semaphore/Mutex... etc** @return the object type information or RT_NULL*/
struct rt_object_information *
rt_object_get_information(enum rt_object_class_type type)
{int index;for (index = 0; index < RT_Object_Info_Unknown; index ++)if (_object_container[index].type == type) return &_object_container[index];return RT_NULL;
}

這個函數用于獲取對象的類型信息,輸入值是rt_object_class_type ,返回值是rt_object_information 指針。它們倆的關系是rt_object_class_type 是rt_object_information 的第一個成員。也就是說通過類型來獲取這個類型的對象的具體信息(后面為了要鏈表)。
它是咋實現的呢。
通過遍歷對象容器_object_container來實現。

rt_object_get_length

/*** @brief This function will return the length of object list in object container.** @param type is the type of object, which can be*             RT_Object_Class_Thread/Semaphore/Mutex... etc** @return the length of object list*/
int rt_object_get_length(enum rt_object_class_type type)
{int count = 0;rt_ubase_t level;struct rt_list_node *node = RT_NULL;struct rt_object_information *information = RT_NULL;information = rt_object_get_information((enum rt_object_class_type)type);if (information == RT_NULL) return 0;level = rt_hw_interrupt_disable();/* get the count of objects */rt_list_for_each(node, &(information->object_list)){count ++;}rt_hw_interrupt_enable(level);return count;
}

這個函數用于獲取對象鏈表的長度,輸入值是rt_object_class_type ,也就是哪一類對象,然后獲取這類對象上的鏈表鏈接的長度。
rt_list_for_each是一個宏,用來遍歷鏈表。

/*** rt_list_for_each - iterate over a list* @pos:    the rt_list_t * to use as a loop cursor.* @head:   the head for your list.*/
#define rt_list_for_each(pos, head) \for (pos = (head)->next; pos != (head); pos = pos->next)

具體實現:先獲取類型的對象信息,對象信息里有一個鏈表節點,這個節點是鏈表頭(哨衛),從次開始遍歷鏈表,從而獲取鏈表長度,注意這個長度是不包含哨衛的。

rt_object_get_pointers

/*** @brief This function will copy the object pointer of the specified type,*        with the maximum size specified by maxlen.** @param type is the type of object, which can be*             RT_Object_Class_Thread/Semaphore/Mutex... etc** @param pointers is the pointer will be saved to.** @param maxlen is the maximum number of pointers can be saved.** @return the copied number of object pointers.*/
int rt_object_get_pointers(enum rt_object_class_type type, rt_object_t *pointers, int maxlen)
{int index = 0;rt_ubase_t level;struct rt_object *object;struct rt_list_node *node = RT_NULL;struct rt_object_information *information = RT_NULL;if (maxlen <= 0) return 0;information = rt_object_get_information((enum rt_object_class_type)type);if (information == RT_NULL) return 0;level = rt_hw_interrupt_disable();/* retrieve pointer of object */rt_list_for_each(node, &(information->object_list)){object = rt_list_entry(node, struct rt_object, list);pointers[index] = object;index ++;if (index >= maxlen) break;}rt_hw_interrupt_enable(level);return index;
}

rt_object_init

/*** @brief This function will initialize an object and add it to object system*        management.** @param object is the specified object to be initialized.** @param type is the object type.** @param name is the object name. In system, the object's name must be unique.*/
void rt_object_init(struct rt_object         *object,enum rt_object_class_type type,const char               *name)
{register rt_base_t temp;struct rt_list_node *node = RT_NULL;struct rt_object_information *information;
#ifdef RT_USING_MODULEstruct rt_dlmodule *module = dlmodule_self();
#endif /* RT_USING_MODULE *//* get object information */information = rt_object_get_information(type);RT_ASSERT(information != RT_NULL);/* check object type to avoid re-initialization *//* enter critical */rt_enter_critical();/* try to find object */for (node  = information->object_list.next;node != &(information->object_list);node  = node->next){struct rt_object *obj;obj = rt_list_entry(node, struct rt_object, list);if (obj) /* skip warning when disable debug */{RT_ASSERT(obj != object);}}/* leave critical */rt_exit_critical();/* initialize object's parameters *//* set object type to static */object->type = type | RT_Object_Class_Static;/* copy name */rt_strncpy(object->name, name, RT_NAME_MAX);RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object));/* lock interrupt */temp = rt_hw_interrupt_disable();#ifdef RT_USING_MODULEif (module){rt_list_insert_after(&(module->object_list), &(object->list));object->module_id = (void *)module;}else
#endif /* RT_USING_MODULE */{/* insert object into information object list */rt_list_insert_after(&(information->object_list), &(object->list));}/* unlock interrupt */rt_hw_interrupt_enable(temp);
}

rt_object_detach

/*** @brief This function will detach a static object from object system,*        and the memory of static object is not freed.** @param object the specified object to be detached.*/
void rt_object_detach(rt_object_t object)
{register rt_base_t temp;/* object check */RT_ASSERT(object != RT_NULL);RT_OBJECT_HOOK_CALL(rt_object_detach_hook, (object));/* reset object type */object->type = 0;/* lock interrupt */temp = rt_hw_interrupt_disable();/* remove from old list */rt_list_remove(&(object->list));/* unlock interrupt */rt_hw_interrupt_enable(temp);
}

如果使用HEAP,#ifdef RT_USING_HEAP ,則有下面的函數rt_object_allocate和rt_object_delete

rt_object_allocate

/*** @brief This function will allocate an object from object system.** @param type is the type of object.** @param name is the object name. In system, the object's name must be unique.** @return object*/
rt_object_t rt_object_allocate(enum rt_object_class_type type, const char *name)
{struct rt_object *object;register rt_base_t temp;struct rt_object_information *information;
#ifdef RT_USING_MODULEstruct rt_dlmodule *module = dlmodule_self();
#endif /* RT_USING_MODULE */RT_DEBUG_NOT_IN_INTERRUPT;/* get object information */information = rt_object_get_information(type);RT_ASSERT(information != RT_NULL);object = (struct rt_object *)RT_KERNEL_MALLOC(information->object_size);if (object == RT_NULL){/* no memory can be allocated */return RT_NULL;}/* clean memory data of object */rt_memset(object, 0x0, information->object_size);/* initialize object's parameters *//* set object type */object->type = type;/* set object flag */object->flag = 0;/* copy name */rt_strncpy(object->name, name, RT_NAME_MAX);RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object));/* lock interrupt */temp = rt_hw_interrupt_disable();#ifdef RT_USING_MODULEif (module){rt_list_insert_after(&(module->object_list), &(object->list));object->module_id = (void *)module;}else
#endif /* RT_USING_MODULE */{/* insert object into information object list */rt_list_insert_after(&(information->object_list), &(object->list));}/* unlock interrupt */rt_hw_interrupt_enable(temp);/* return object */return object;
}

rt_object_delete

/*** @brief This function will delete an object and release object memory.** @param object is the specified object to be deleted.*/
void rt_object_delete(rt_object_t object)
{register rt_base_t temp;/* object check */RT_ASSERT(object != RT_NULL);RT_ASSERT(!(object->type & RT_Object_Class_Static));RT_OBJECT_HOOK_CALL(rt_object_detach_hook, (object));/* reset object type */object->type = RT_Object_Class_Null;/* lock interrupt */temp = rt_hw_interrupt_disable();/* remove from old list */rt_list_remove(&(object->list));/* unlock interrupt */rt_hw_interrupt_enable(temp);/* free the memory of object */RT_KERNEL_FREE(object);
}

rt_object_is_systemobject

/*** @brief This function will judge the object is system object or not.** @note  Normally, the system object is a static object and the type*        of object set to RT_Object_Class_Static.** @param object is the specified object to be judged.** @return RT_TRUE if a system object, RT_FALSE for others.*/
rt_bool_t rt_object_is_systemobject(rt_object_t object)
{/* object check */RT_ASSERT(object != RT_NULL);if (object->type & RT_Object_Class_Static)return RT_TRUE;return RT_FALSE;
}

rt_object_get_type

/*** @brief This function will return the type of object without*        RT_Object_Class_Static flag.** @param object is the specified object to be get type.** @return the type of object.*/
rt_uint8_t rt_object_get_type(rt_object_t object)
{/* object check */RT_ASSERT(object != RT_NULL);return object->type & ~RT_Object_Class_Static;
}

rt_object_find

/*** @brief This function will find specified name object from object*        container.** @param name is the specified name of object.** @param type is the type of object** @return the found object or RT_NULL if there is no this object* in object container.** @note this function shall not be invoked in interrupt status.*/
rt_object_t rt_object_find(const char *name, rt_uint8_t type)
{struct rt_object *object = RT_NULL;struct rt_list_node *node = RT_NULL;struct rt_object_information *information = RT_NULL;information = rt_object_get_information((enum rt_object_class_type)type);/* parameter check */if ((name == RT_NULL) || (information == RT_NULL)) return RT_NULL;/* which is invoke in interrupt status */RT_DEBUG_NOT_IN_INTERRUPT;/* enter critical */rt_enter_critical();/* try to find object */rt_list_for_each(node, &(information->object_list)){object = rt_list_entry(node, struct rt_object, list);if (rt_strncmp(object->name, name, RT_NAME_MAX) == 0){/* leave critical */rt_exit_critical();return object;}}/* leave critical */rt_exit_critical();return RT_NULL;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/41092.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/41092.shtml
英文地址,請注明出處:http://en.pswp.cn/web/41092.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

清新簡約之美,開源個人博客:Jekyll Theme Chirpy

Jekyll Theme Chirpy&#xff1a;簡約不簡單&#xff0c;Chirpy 讓你的博客煥發新意- 精選真開源&#xff0c;釋放新價值。 概覽 Jekyll Theme Chirpy 是為Jekyll靜態網站生成器設計的現代主題&#xff0c;以其清新、簡約的設計風格和用戶友好的交互體驗受到開發者和博客作者的…

為企業知識庫選模型?全球AI大模型知識庫RAG場景基準測試排名

大語言模型常見基準測試 大家對于AI模型理解和推理能力的的基準測試一定非常熟悉了&#xff0c;比如MMLU&#xff08;大規模多任務語言理解&#xff09;、GPQA&#xff08;研究生級別知識問答&#xff09;、GSMSK&#xff08;研究生數學知識考察&#xff09;、MATH&#xff08…

Zabbix監控軟件

目錄 一、什么是Zabbix 二、zabbix監控原理 三、zabbix 安裝步驟 一、什么是Zabbix ●zabbix 是一個基于 Web 界面的提供分布式系統監視以及網絡監視功能的企業級的開源解決方案。 ●zabbix 能監視各種網絡參數&#xff0c;保證服務器系統的安全運營&#xff1b;并提供靈活的…

python讀取寫入txt文本文件

讀取 txt 文件 def read_txt_file(file_path):"""讀取文本文件的內容:param file_path: 文本文件的路徑:return: 文件內容"""try:with open(file_path, r, encodingutf-8) as file:content file.read()return contentexcept FileNotFoundError…

Swagger的原理及應用詳解(十)

本系列文章簡介&#xff1a; 在當今快速發展的軟件開發領域&#xff0c;特別是隨著微服務架構和前后端分離開發模式的普及&#xff0c;API&#xff08;Application Programming Interface&#xff0c;應用程序編程接口&#xff09;的設計與管理變得愈發重要。一個清晰、準確且易…

【多線程】進程與線程

&#x1f3c0;&#x1f3c0;&#x1f3c0;來都來了&#xff0c;不妨點個關注&#xff01; &#x1f3a7;&#x1f3a7;&#x1f3a7;博客主頁&#xff1a;歡迎各位大佬! 文章目錄 1. 操作系統1.1 什么是操作系統1.2 操作系統主要的功能 2. 進程2.1 什么是進程2.2 通過PCB描述一…

jEasyUI 創建菜單按鈕

jEasyUI 創建菜單按鈕 jEasyUI(jQuery EasyUI)是一個基于jQuery的用戶界面插件集合,它為用戶提供了一系列的UI組件,如菜單、按鈕、表格等,以簡化Web頁面的開發過程。在本文中,我們將重點介紹如何使用jEasyUI創建菜單按鈕。 1. 環境準備 在開始之前,請確保您的開發環境…

使用Python繪制甘特圖

使用Python繪制甘特圖 甘特圖效果代碼 甘特圖 甘特圖是一種項目管理工具&#xff0c;用于展示項目進度和任務安排。它通過條狀圖形表示各任務的起止時間&#xff0c;便于直觀地查看項目的各個任務的進度和相互關系。 效果 [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片…

(void) (_x == _y)的作用

在閱讀宋寶華的《Linux設備驅動開發詳解》一書時&#xff0c;看到下面這段代碼&#xff1a; #define min(x, y) ({ \ const typeof(x) _x (x); \ const typeof(y) -y (y); \ (void) (&_x &_y); \ _x < _y ? _x : _y; }) 這段代碼可以理解如…

變量和標識符

一、變量 變量 數據類型 變量名初始值 常量的定義方式 1.#define 宏常量 (Day是常量&#xff0c;一旦修改就會報錯) /2.const修飾的變量 #include <iostream> using namespace std; //變量 數據類型 變量名初始值 //常量的定義方式 //1.#define 宏常量 (Day是常量&…

Vue.js 基礎入門指南

前言 在前端開發的廣闊領域中&#xff0c;Vue.js 無疑是一顆璀璨的明星&#xff0c;以其漸進式框架的特性吸引了無數開發者的目光。Vue.js 旨在通過簡潔的 API 實現響應式的數據綁定和組合的視圖組件&#xff0c;使得構建用戶界面變得既快速又簡單。本文將帶你走進 Vue.js 的世…

學習探索RASP:下一代應用安全防護技術

在當今數字化浪潮中&#xff0c;各類信息系統、應用程序不僅是企業數字化轉型的驅動力&#xff0c;也成為了網絡攻擊的集中地帶。面對日益復雜多變的網絡安全威脅&#xff0c;防火墻等傳統防護手段逐漸顯得力不從心。在此背景下&#xff0c;尋求一種更為智能、高效且能深度融入…

代碼隨想錄算法訓練營第22天|LeetCode 77. 組合、216.組合總和III、17.電話號碼的字母組合

1. LeetCode 77. 組合 題目鏈接&#xff1a;https://leetcode.cn/problems/combinations/description/ 文章鏈接&#xff1a;https://programmercarl.com/0077.組合.html 視頻鏈接&#xff1a;https://www.bilibili.com/video/BV1ti4y1L7cv 思路&#xff1a;利用遞歸回溯的方式…

Codeforces Round 954 (Div. 3)

這里寫自定義目錄標題 A. X Axis題意&#xff1a;題解&#xff1a;代碼&#xff1a; B. Matrix Stabilization題意&#xff1a;題解&#xff1a;代碼&#xff1a; C. Update Queries題意&#xff1a;題解&#xff1a;代碼&#xff1a; D. Mathematical Problem題意&#xff1a;…

nanodiffusion代碼逐行理解之diffusion

目錄 一、diffusion創建二、GaussianDiffusion定義三、代碼理解def __init__(self,model,img_size,img_channels,num_classes,betas, loss_type"l2", ema_decay0.9999, ema_start5000, ema_update_rate1,):def remove_noise(self, x, t, y, use_emaTrue):def sample(…

MySQL 集群

MySQL 集群有多種類型&#xff0c;每種類型都有其特定的用途和優勢。以下是一些常見的 MySQL 集群解決方案&#xff1a; 1. MySQL Replication 描述&#xff1a;MySQL 復制是一種異步復制機制&#xff0c;允許將一個 MySQL 數據庫的數據復制到一個或多個從服務器。 用途&…

bug——多重定義

bug——多重定義 你的問題是在C代碼中遇到了"reference to data is ambiguous"的錯誤。這個錯誤通常發生在你嘗試引用一個具有多重定義的變量時。 在你的代碼中&#xff0c;你定義了一個全局變量data&#xff0c;同時&#xff0c;C標準庫中也有一個名為data的函數模板…

【云原生】Kubernetes部署高可用平臺手冊

部署Kubernetes高可用平臺 文章目錄 部署Kubernetes高可用平臺基礎環境一、基礎環境配置1.1、關閉Swap1.2、添加hosts解析1.3、橋接IPv4流量傳遞到iptables的鏈 二、配置Kubernetes的VIP2.1、安裝Nginx2.2、修改Nginx配置文件2.3、啟動服務2.4、安裝Keepalived2.5、修改配置文件…

Linux 定時任務詳解:全面掌握 cron 和 at 命令

Linux 定時任務詳解&#xff1a;全面掌握 cron 和 at 命令 Linux 系統中定時任務的管理對于運維和開發人員來說都是至關重要的。通過定時任務&#xff0c;可以在特定時間自動執行腳本或命令&#xff0c;提高系統自動化程度。本文將詳細介紹 Linux 中常用的定時任務管理工具 cr…

一拖二快充線:生活充電新風尚,高效便捷解決雙設備充電難題

一拖二快充線在生活應用領域的優勢與雙接充電的便攜性問題 在現代快節奏的生活中&#xff0c;電子設備已成為我們不可或缺的日常伴侶。無論是智能手機、平板電腦還是筆記本電腦&#xff0c;它們在我們的工作、學習和娛樂中扮演著至關重要的角色。然而&#xff0c;隨著設備數量…