這篇文章主要介紹“TencentOS tiny任務(wù)的基本概念和相關(guān)操作介紹”,在日常操作中,相信很多人在TencentOS tiny任務(wù)的基本概念和相關(guān)操作介紹問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”TencentOS tiny任務(wù)的基本概念和相關(guān)操作介紹”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!
創(chuàng)新互聯(lián)公司專注于網(wǎng)站建設(shè)|成都網(wǎng)站改版|優(yōu)化|托管以及網(wǎng)絡(luò)推廣,積累了大量的網(wǎng)站設(shè)計(jì)與制作經(jīng)驗(yàn),為許多企業(yè)提供了網(wǎng)站定制設(shè)計(jì)服務(wù),案例作品覆蓋成都酒樓設(shè)計(jì)等行業(yè)。能根據(jù)企業(yè)所處的行業(yè)與銷售的產(chǎn)品,結(jié)合品牌形象的塑造,量身建設(shè)品質(zhì)網(wǎng)站。
從系統(tǒng)的角度看,任務(wù)是競(jìng)爭(zhēng)系統(tǒng)資源的最小運(yùn)行單元。TencentOS tiny是一個(gè)支持多任務(wù)的操作系統(tǒng),任務(wù)可以使用或等待CPU、使用內(nèi)存空間等系統(tǒng)資源,并獨(dú)立于其它任務(wù)運(yùn)行,理論上任何數(shù)量的任務(wù)都可以共享同一個(gè)優(yōu)先級(jí),這樣子處于就緒態(tài)的多個(gè)相同優(yōu)先級(jí)任務(wù)將會(huì)以時(shí)間片切換的方式共享處理器。
不過(guò)要注意的是:在TencentOS tiny中,不能創(chuàng)建與空閑任務(wù)相同優(yōu)先級(jí)的任務(wù)
K_TASK_PRIO_IDLE
,相同優(yōu)先級(jí)下的任務(wù)需要允許使用時(shí)間片調(diào)度,打開(kāi)TOS_CFG_ROUND_ROBIN_EN
。
簡(jiǎn)而言之: TencentOS tiny的任務(wù)可認(rèn)為是一系列獨(dú)立任務(wù)的集合。每個(gè)任務(wù)在自己的環(huán)境中運(yùn)行。在任何時(shí)刻,只有一個(gè)任務(wù)得到運(yùn)行,由TencentOS tiny調(diào)度器決定運(yùn)行哪個(gè)任務(wù)。從宏觀
看上去所有的任務(wù)都在同時(shí)在執(zhí)行。
TencentOS中的任務(wù)是搶占式調(diào)度機(jī)制,高優(yōu)先級(jí)的任務(wù)可打斷低優(yōu)先級(jí)任務(wù),低優(yōu)先級(jí)任務(wù)必須在高優(yōu)先級(jí)任務(wù)阻塞或結(jié)束后才能得到調(diào)度。同時(shí)TencentOS也支持時(shí)間片輪轉(zhuǎn)調(diào)度方式。
系統(tǒng)默認(rèn)可以支持10個(gè)優(yōu)先級(jí),0~TOS_CFG_TASK_PRIO_MAX
,這個(gè)宏定義是可以修改的,優(yōu)先級(jí)數(shù)值越大的任務(wù)優(yōu)先級(jí)越低,(TOS_CFG_TASK_PRIO_MAX - (k_prio_t)1u)
為最低優(yōu)先級(jí),分配給空閑任務(wù)使用。
#define K_TASK_PRIO_IDLE (k_prio_t)(TOS_CFG_TASK_PRIO_MAX - (k_prio_t)1u) #define K_TASK_PRIO_INVALID (k_prio_t)(TOS_CFG_TASK_PRIO_MAX)
TencentOS tiny任務(wù)狀態(tài)有以下幾種。
就緒態(tài)(K_TASK_STATE_READY):該任務(wù)在就緒列表中,就緒的任務(wù)已經(jīng)具備執(zhí)行的能力,只等待調(diào)度器進(jìn)行調(diào)度,新創(chuàng)建的任務(wù)會(huì)初始化為就緒態(tài)。
運(yùn)行態(tài)(K_TASK_STATE_READY):該狀態(tài)表明任務(wù)正在執(zhí)行,此時(shí)它占用處理器,其實(shí)此時(shí)的任務(wù)還是處于就緒列表中的,TencentOS調(diào)度器選擇運(yùn)行的永遠(yuǎn)是處于最高優(yōu)先級(jí)的就緒態(tài)任務(wù),當(dāng)任務(wù)被運(yùn)行的一刻,它的任務(wù)狀態(tài)就變成了運(yùn)行態(tài)。
睡眠態(tài)(K_TASK_STATE_SLEEP):如果任務(wù)當(dāng)前正在休眠讓出CPU使用權(quán),那么就可以說(shuō)這個(gè)任務(wù)處于休眠狀態(tài),該任務(wù)不在就緒列表中,此時(shí)任務(wù)處于睡眠列表中(或者叫延時(shí)列表)。
等待態(tài)(K_TASK_STATE_PEND):任務(wù)正在等待信號(hào)量、隊(duì)列或者等待事件等狀態(tài)。
掛起態(tài)(K_TASK_STATE_SUSPENDED):任務(wù)被掛起,此時(shí)任務(wù)對(duì)調(diào)度器而言是不可見(jiàn)的。
退出態(tài)(K_TASK_STATE_DELETED):該任務(wù)運(yùn)行結(jié)束,并且被刪除。
等待超時(shí)狀態(tài)(K_TASK_STATE_PENDTIMEOUT):任務(wù)正在等待信號(hào)量、隊(duì)列或者等待事件發(fā)生超時(shí)的狀態(tài)。
睡眠掛起態(tài)(K_TASK_STATE_SLEEP_SUSPENDED):任務(wù)在睡眠中被掛起時(shí)的狀態(tài)。
等待掛起態(tài)(K_TASK_STATE_PEND_SUSPENDED):任務(wù)正在等待信號(hào)量、隊(duì)列或者等待事件時(shí)被掛起的狀態(tài)。
等待超時(shí)掛起態(tài)(K_TASK_STATE_PENDTIMEOUT_SUSPENDED):任務(wù)正在等待信號(hào)量、隊(duì)列或者等待事件發(fā)生超時(shí),但此時(shí)任務(wù)已經(jīng)被掛起的狀態(tài)。
// ready to schedule // a task's pend_list is in readyqueue #define K_TASK_STATE_READY (k_task_state_t)0x0000 // delayed, or pend for a timeout // a task's tick_list is in k_tick_list #define K_TASK_STATE_SLEEP (k_task_state_t)0x0001 // pend for something // a task's pend_list is in some pend object's list #define K_TASK_STATE_PEND (k_task_state_t)0x0002 // suspended #define K_TASK_STATE_SUSPENDED (k_task_state_t)0x0004 // deleted #define K_TASK_STATE_DELETED (k_task_state_t)0x0008 // actually we don't really need those TASK_STATE below, if you understand the task state deeply, the code can be much more elegant. // we are pending, also we are waitting for a timeout(eg. tos_sem_pend with a valid timeout, not TOS_TIME_FOREVER) // both a task's tick_list and pend_list is not empty #define K_TASK_STATE_PENDTIMEOUT (k_task_state_t)(K_TASK_STATE_PEND | K_TASK_STATE_SLEEP) // suspended when sleeping #define K_TASK_STATE_SLEEP_SUSPENDED (k_task_state_t)(K_TASK_STATE_SLEEP | K_TASK_STATE_SUSPENDED) // suspened when pending #define K_TASK_STATE_PEND_SUSPENDED (k_task_state_t)(K_TASK_STATE_PEND | K_TASK_STATE_SUSPENDED) // suspended when pendtimeout #define K_TASK_STATE_PENDTIMEOUT_SUSPENDED (k_task_state_t)(K_TASK_STATE_PENDTIMEOUT | K_TASK_STATE_SUSPENDED)
TencentOS tiny維護(hù)一條就緒列表,用于掛載系統(tǒng)中的所有處于就緒態(tài)的任務(wù),他是readyqueue_t
類型的列表,其成員變量如下:
readyqueue_t k_rdyq; typedef struct readyqueue_st { k_list_t task_list_head[TOS_CFG_TASK_PRIO_MAX]; uint32_t prio_mask[K_PRIO_TBL_SIZE]; k_prio_t highest_prio; } readyqueue_t;
task_list_head
是列表類型k_list_t
的數(shù)組,TencentOS tiny為每個(gè)優(yōu)先級(jí)的任務(wù)都分配一個(gè)列表,系統(tǒng)支持最大優(yōu)先級(jí)為TOS_CFG_TASK_PRIO_MAX
prio_mask
則是優(yōu)先級(jí)掩碼數(shù)組,它是一個(gè)類型為32位變量的數(shù)組,數(shù)組成員個(gè)數(shù)由TOS_CFG_TASK_PRIO_MAX
決定:
#define K_PRIO_TBL_SIZE ((TOS_CFG_TASK_PRIO_MAX + 31) / 32)
當(dāng)TOS_CFG_TASK_PRIO_MAX
不超過(guò)32時(shí)數(shù)組成員變量只有一個(gè),就是32位的變量數(shù)值,那么該變量的每一位代表一個(gè)優(yōu)先級(jí)。比如當(dāng)TOS_CFG_TASK_PRIO_MAX
為64時(shí),prio_mask[0]
變量的每一位(bit)代表0-31
優(yōu)先級(jí),而prio_mask[1]
變量的每一位代表32-63
優(yōu)先級(jí)。
highest_prio
則是記錄當(dāng)前優(yōu)先級(jí)列表的最高優(yōu)先級(jí),方便索引task_list_head
。
與系統(tǒng)時(shí)間相關(guān)的任務(wù)都會(huì)被掛載到這個(gè)列表中,可能是睡眠、有期限地等待信號(hào)量、事件、消息隊(duì)列等情況~
k_list_t k_tick_list;
在多任務(wù)系統(tǒng)中,任務(wù)的執(zhí)行是由系統(tǒng)調(diào)度的。系統(tǒng)為了順利的調(diào)度任務(wù),為每個(gè)任務(wù)都額外定義了一個(gè)任務(wù)控制塊,這個(gè)任務(wù)控制塊就相當(dāng)于任務(wù)的身份證,里面存有任務(wù)的所有信息,比如任務(wù)的棧指針,任務(wù)名稱,任務(wù)的形參等。有了這個(gè)任務(wù)控制塊之后,以后系統(tǒng)對(duì)任務(wù)的全部操作都可以通過(guò)這個(gè)任務(wù)控制塊來(lái)實(shí)現(xiàn)。 TencentOS 任務(wù)控制塊如下:
typedef struct k_task_st { k_stack_t *sp; /**< 任務(wù)棧指針,用于切換上下文*/ #if TOS_CFG_OBJECT_VERIFY_EN > 0u knl_obj_t knl_obj; /**< 只是為了驗(yàn)證,測(cè)試當(dāng)前對(duì)象是否真的是一項(xiàng)任務(wù)。*/ #endif char *name; /**< 任務(wù)名稱 */ k_task_entry_t entry; /**< 任務(wù)主體 */ void *arg; /**< 任務(wù)主體形參 */ k_task_state_t state; /**< 任務(wù)狀態(tài) */ k_prio_t prio; /**< 任務(wù)優(yōu)先級(jí) */ k_stack_t *stk_base; /**< 任務(wù)?;刂?nbsp;*/ size_t stk_size; /**< 任務(wù)棧大小 */ k_tick_t tick_expires; /**< 任務(wù)阻塞的時(shí)間 */ k_list_t tick_list; /**< 延時(shí)列表 */ k_list_t pend_list; /**< 就緒、等待列表 */ #if TOS_CFG_MUTEX_EN > 0u k_list_t mutex_own_list; /**< 任務(wù)擁有的互斥量 */ k_prio_t prio_pending; /*< 用于記錄持有互斥量的任務(wù)初始優(yōu)先級(jí),在優(yōu)先級(jí)繼承中使用 */ #endif pend_obj_t *pending_obj; /**< 記錄任務(wù)此時(shí)掛載到的列表 */ pend_state_t pend_state; /**< 等待被喚醒的原因(狀態(tài)) */ #if TOS_CFG_ROUND_ROBIN_EN > 0u k_timeslice_t timeslice_reload; /**< 時(shí)間片初始值(重裝載值) */ k_timeslice_t timeslice; /**< 剩余時(shí)間片 */ #endif #if TOS_CFG_MSG_EN > 0u void *msg_addr; /**< 保存接收到的消息 */ size_t msg_size; /**< 保存接收到的消息大小 */ #endif #if TOS_CFG_EVENT_EN > 0u k_opt_t opt_event_pend; /**< 等待事件的的操作類型:TOS_OPT_EVENT_PEND_ANY 、 TOS_OPT_EVENT_PEND_ALL */ k_event_flag_t flag_expect; /**< 期待發(fā)生的事件 */ k_event_flag_t *flag_match; /**< 等待到的事件 */ #endif } k_task_t;
在TencentOS tiny中,凡是使用__API__
修飾的函數(shù)都是提供給用戶使用的,而使用__KERNEL__
修飾的代碼則是給內(nèi)核使用的。 TencentOS的創(chuàng)建任務(wù)函數(shù)有好幾個(gè)參數(shù): |參數(shù)| 含義 | |--|--| |task | 任務(wù)控制塊 | |name | 任務(wù)名字 | |entry | 任務(wù)主體 | |arg | 任務(wù)形參 | |prio | 優(yōu)先級(jí) | |stk_base | 任務(wù)?;刂?| |stk_size | 任務(wù)棧大小 | |timeslice | 時(shí)間片 |
參數(shù)詳解(來(lái)源TencentOS tiny開(kāi)發(fā)指南):
task
這是一個(gè)k_task_t類型的指針,k_task_t是內(nèi)核的任務(wù)結(jié)構(gòu)體類型。注意:task指針,應(yīng)該指向生命周期大于待創(chuàng)建任務(wù)體生命周期的k_task_t類型變量,如果該指針指向的變量生命周期比待創(chuàng)建的任務(wù)體生命周期短,譬如可能是一個(gè)生命周期極端的函數(shù)棧上變量,可能會(huì)出現(xiàn)任務(wù)體還在運(yùn)行而k_task_t變量已被銷毀,會(huì)導(dǎo)致系統(tǒng)調(diào)度出現(xiàn)不可預(yù)知問(wèn)題。
name
指向任務(wù)名字符串的指針。注意:同task,該指針指向的字符串生命周期應(yīng)該大于待創(chuàng)建的任務(wù)體生命周期,一般來(lái)說(shuō),傳入字符串常量指針即可。
entry
任務(wù)體運(yùn)行的函數(shù)入口。當(dāng)任務(wù)創(chuàng)建完畢進(jìn)入運(yùn)行狀態(tài)后,entry是任務(wù)執(zhí)行的入口,用戶可以在此函數(shù)中編寫業(yè)務(wù)邏輯。
arg
傳遞給任務(wù)入口函數(shù)的參數(shù)。
prio
任務(wù)優(yōu)先級(jí)。prio的數(shù)值越小,優(yōu)先級(jí)越高。用戶可以在tos_config.h中,通過(guò)TOS_CFG_TASK_PRIO_MAX來(lái)配置任務(wù)優(yōu)先級(jí)的最大數(shù)值,在內(nèi)核的實(shí)現(xiàn)中,idle任務(wù)的優(yōu)先級(jí)會(huì)被分配為TOS_CFG_TASK_PRIO_MAX - 1,此優(yōu)先級(jí)只能被idle任務(wù)使用。因此對(duì)于一個(gè)用戶創(chuàng)建的任務(wù)來(lái)說(shuō),合理的優(yōu)先級(jí)范圍應(yīng)該為[0, TOS_CFG_TASK_PRIO_MAX - 2]。另外TOS_CFG_TASK_PRIO_MAX的配置值必需大于等于8。
stk_base
任務(wù)在運(yùn)行時(shí)使用的棧空間的起始地址。注意:同task,該指針指向的內(nèi)存空間的生命周期應(yīng)該大于待創(chuàng)建的任務(wù)體生命周期。stk_base是k_stack_t類型的數(shù)組起始地址。
stk_size
任務(wù)的棧空間大小。注意:因?yàn)閟tk_base是k_stack_t類型的數(shù)組指針,因此實(shí)際棧空間所占內(nèi)存大小為stk_size * sizeof(k_stack_t)。
timeslice
時(shí)間片輪轉(zhuǎn)機(jī)制下當(dāng)前任務(wù)的時(shí)間片大小。當(dāng)timeslice為0時(shí),任務(wù)調(diào)度時(shí)間片會(huì)被設(shè)置為默認(rèn)大小(TOS_CFG_CPU_TICK_PER_SECOND / 10),系統(tǒng)時(shí)鐘滴答(systick)數(shù) / 10。
創(chuàng)建任務(wù)的實(shí)現(xiàn)如下:首先對(duì)參數(shù)進(jìn)行檢查,還要再提一下:在TencentOS中,不能創(chuàng)建與空閑任務(wù)相同優(yōu)先級(jí)的任務(wù)K_TASK_PRIO_IDLE
。然后調(diào)用cpu_task_stk_init
函數(shù)將任務(wù)棧進(jìn)行初始化,并且將傳入的參數(shù)記錄到任務(wù)控制塊中。如果打開(kāi)了TOS_CFG_ROUND_ROBIN_EN
宏定義,則表示支持時(shí)間片調(diào)度,則需要配置時(shí)間片相關(guān)的信息timeslice
到任務(wù)控制塊中。然后調(diào)用task_state_set_ready
函數(shù)將新創(chuàng)建的任務(wù)設(shè)置為就緒態(tài)K_TASK_STATE_READY
,再調(diào)用readyqueue_add_tail
函數(shù)將任務(wù)插入就緒列表k_rdyq
中。如果調(diào)度器運(yùn)行起來(lái)了,則進(jìn)行一次任務(wù)調(diào)度。
個(gè)人感覺(jué)吧,沒(méi)有從堆中動(dòng)態(tài)分配還是有點(diǎn)小小的遺憾,我更喜歡簡(jiǎn)單的函數(shù)接口~!
代碼如下:
__API__ k_err_t tos_task_create(k_task_t *task, char *name, k_task_entry_t entry, void *arg, k_prio_t prio, k_stack_t *stk_base, size_t stk_size, k_timeslice_t timeslice) { TOS_CPU_CPSR_ALLOC(); TOS_IN_IRQ_CHECK(); TOS_PTR_SANITY_CHECK(task); TOS_PTR_SANITY_CHECK(entry); TOS_PTR_SANITY_CHECK(stk_base); if (unlikely(stk_size < sizeof(cpu_context_t))) { return K_ERR_TASK_STK_SIZE_INVALID; } if (unlikely(prio == K_TASK_PRIO_IDLE && !knl_is_idle(task))) { return K_ERR_TASK_PRIO_INVALID; } if (unlikely(prio > K_TASK_PRIO_IDLE)) { return K_ERR_TASK_PRIO_INVALID; } task_reset(task); #if TOS_CFG_OBJECT_VERIFY_EN > 0u knl_object_init(&task->knl_obj, KNL_OBJ_TYPE_TASK); #endif task->sp = cpu_task_stk_init((void *)entry, arg, (void *)task_exit, stk_base, stk_size); task->entry = entry; task->arg = arg; task->name = name; task->prio = prio; task->stk_base = stk_base; task->stk_size = stk_size; #if TOS_CFG_ROUND_ROBIN_EN > 0u task->timeslice_reload = timeslice; if (timeslice == (k_timeslice_t)0u) { task->timeslice = k_robin_default_timeslice; } else { task->timeslice = timeslice; } #endif TOS_CPU_INT_DISABLE(); task_state_set_ready(task); readyqueue_add_tail(task); TOS_CPU_INT_ENABLE(); if (tos_knl_is_running()) { knl_sched(); } return K_ERR_NONE; }
這個(gè)函數(shù)十分簡(jiǎn)單,根據(jù)傳遞進(jìn)來(lái)的任務(wù)控制塊銷毀任務(wù),也可以傳遞進(jìn)NULL表示銷毀當(dāng)前運(yùn)行的任務(wù)。但是不允許銷毀空閑任務(wù)k_idle_task
,當(dāng)調(diào)度器被鎖住時(shí)不能銷毀自身,會(huì)返回K_ERR_SCHED_LOCKED
錯(cuò)誤代碼。如果使用了互斥量,當(dāng)任務(wù)被銷毀時(shí)會(huì)釋放掉互斥量,并且根據(jù)任務(wù)所處的狀態(tài)進(jìn)行銷毀,比如任務(wù)處于就緒態(tài)、延時(shí)態(tài)、等待態(tài),則會(huì)從對(duì)應(yīng)的狀態(tài)列表
中移除。 代碼實(shí)現(xiàn)如下:
__API__ k_err_t tos_task_destroy(k_task_t *task) { TOS_CPU_CPSR_ALLOC(); TOS_IN_IRQ_CHECK(); if (unlikely(!task)) { task = k_curr_task; } #if TOS_CFG_OBJECT_VERIFY_EN > 0u if (!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK)) { return K_ERR_OBJ_INVALID; } #endif if (knl_is_idle(task)) { return K_ERR_TASK_DESTROY_IDLE; } if (knl_is_self(task) && knl_is_sched_locked()) { return K_ERR_SCHED_LOCKED; } TOS_CPU_INT_DISABLE(); #if TOS_CFG_MUTEX_EN > 0u // when we die, wakeup all the people in this land. if (!tos_list_empty(&task->mutex_own_list)) { task_mutex_release(task); } #endif if (task_state_is_ready(task)) { // that's simple, good kid readyqueue_remove(task); } if (task_state_is_sleeping(task)) { tick_list_remove(task); } if (task_state_is_pending(task)) { pend_list_remove(task); } task_reset(task); task_state_set_deleted(task); TOS_CPU_INT_ENABLE(); knl_sched(); return K_ERR_NONE; }
任務(wù)睡眠非常簡(jiǎn)單,主要的思路就是將任務(wù)從就緒列表移除,然后添加到延時(shí)列表中k_tick_list
,如果調(diào)度器被鎖,直接返回錯(cuò)誤代碼K_ERR_SCHED_LOCKED
,如果睡眠時(shí)間為0,則調(diào)用tos_task_yield
函數(shù)發(fā)起一次任務(wù)調(diào)度;調(diào)用tick_list_add
函數(shù)將任務(wù)插入延時(shí)列表
中,睡眠的時(shí)間delay
是由用戶指定的。不過(guò)需要注意的是如果任務(wù)睡眠的時(shí)間是永久睡眠TOS_TIME_FOREVER
,將返回錯(cuò)誤代碼K_ERR_DELAY_FOREVER
,這是因?yàn)槿蝿?wù)睡眠是主動(dòng)行為
,如果永久睡眠了,將沒(méi)法主動(dòng)喚醒,而任務(wù)等待事件、信號(hào)量、消息隊(duì)列等行為是被動(dòng)行為,可以是永久等待,一旦事件發(fā)生了、信號(hào)量唄釋放、消息隊(duì)列不為空時(shí)任務(wù)就會(huì)被喚醒,這是被動(dòng)行為
,這兩點(diǎn)需要區(qū)分開(kāi)來(lái)。最后調(diào)用readyqueue_remove
函數(shù)將任務(wù)從就緒列表中移除,然后調(diào)用knl_sched
函數(shù)發(fā)起一次任務(wù)調(diào)度,就能切換另一個(gè)任務(wù)。 任務(wù)睡眠的代碼如下:
__API__ k_err_t tos_task_delay(k_tick_t delay) { TOS_CPU_CPSR_ALLOC(); TOS_IN_IRQ_CHECK(); if (knl_is_sched_locked()) { return K_ERR_SCHED_LOCKED; } if (unlikely(delay == (k_tick_t)0u)) { tos_task_yield(); return K_ERR_NONE; } TOS_CPU_INT_DISABLE(); if (tick_list_add(k_curr_task, delay) != K_ERR_NONE) { TOS_CPU_INT_ENABLE(); return K_ERR_DELAY_FOREVER; } readyqueue_remove(k_curr_task); TOS_CPU_INT_ENABLE(); knl_sched(); return K_ERR_NONE; }
到此,關(guān)于“TencentOS tiny任務(wù)的基本概念和相關(guān)操作介紹”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!
分享名稱:TencentOStiny任務(wù)的基本概念和相關(guān)操作介紹
路徑分享:http://muchs.cn/article22/gedpjc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站收錄、關(guān)鍵詞優(yōu)化、小程序開(kāi)發(fā)、網(wǎng)站策劃、網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)