鴻蒙內核源碼分析:Task/線程管理篇

2021-02-14 CSDN

作者 | 深入研究鴻蒙,鴻蒙內核發燒友

出品 | CSDN(ID:CSDNnews)

怎麼理解Task


1、官方文檔是怎麼描述線程基本概念

從系統的角度看,線程是競爭系統資源的最小運行單元。線程可以使用或等待CPU、使用內存空間等系統資源,並獨立於其它線程運行。

鴻蒙內核每個進程內的線程獨立運行、獨立調度,當前進程內線程的調度不受其它進程內線程的影響。

鴻蒙內核中的線程採用搶佔式調度機制,同時支持時間片輪轉調度和FIFO調度方式。

鴻蒙內核的線程一共有32個優先級(0-31),最高優先級為0,最低優先級為31。

當前進程內高優先級的線程可搶佔當前進程內低優先級線程,當前進程內低優先級線程必須在當前進程內高優先級線程阻塞或結束後才能得到調度。

線程狀態說明:

初始化(Init):該線程正在被創建。

就緒(Ready):該線程在就緒列表中,等待CPU調度。

運行(Running):該線程正在運行。

阻塞(Blocked):該線程被阻塞掛起。Blocked狀態包括:pend(因為鎖、事件、信號量等阻塞)、suspend(主動pend)、delay(延時阻塞)、pendtime(因為鎖、事件、信號量時間等超時等待)。

退出(Exit):該線程運行結束,等待父線程回收其控制塊資源。

圖 1 線程狀態遷移示意圖

注意官方文檔說的是線程,沒有提到task(任務),但內核源碼中卻有大量 task代碼,很少有線程(thread)代碼 ,這是怎麼回事?其實在鴻蒙內核中, task就是線程, 初學者完全可以這麼理解,但二者還是有區別,否則幹嘛要分兩個詞描述。到底有什麼區別?是管理上的區別,task是調度層面的概念,線程是進程層面的概念。就像同一個人在不同的管理體系中會有不同的身份一樣,一個男人既可以是 孩子,爸爸,丈夫,或者程式設計師,視角不同功能也會不同。2、執行task命令

鴻蒙 task 命令的執行結果:

task命令 查出每個任務在生命周期內的運行情況,它運行的內存空間,優先級,時間片,入口執行函數,進程ID,狀態等等信息,非常的複雜。這麼複雜的信息就需要一個結構體來承載。而這個結構體就是 LosTaskCB(任務控制塊)

對應張大爺的故事:task就是一個用戶的節目清單裡的一個節目,用戶總清單就是一個進程,所以上面會有很多的節目。

3、task長得什麼樣子?

說LosTaskCB之前先說下官方文檔任務狀態對應的 define,可以看出task和線程是一個東西。 

#define OS_TASK_STATUS_INIT         0x0001U#define OS_TASK_STATUS_READY        0x0002U#define OS_TASK_STATUS_RUNNING      0x0004U#define OS_TASK_STATUS_SUSPEND      0x0008U#define OS_TASK_STATUS_PEND         0x0010U#define OS_TASK_STATUS_DELAY        0x0020U#define OS_TASK_STATUS_TIMEOUT      0x0040U#define OS_TASK_STATUS_PEND_TIME    0x0080U#define OS_TASK_STATUS_EXIT         0x0100U

LosTaskCB長什麼樣?抱歉,它確實有點長,但還是要全部貼出全貌。

typedef struct {    VOID            *stackPointer;          UINT16          taskStatus;             UINT16          priority;               UINT16          policy;    UINT16          timeSlice;              UINT32          stackSize;              UINTPTR         topOfStack;             UINT32          taskID;                 TSK_ENTRY_FUNC  taskEntry;              VOID            *joinRetval;            VOID            *taskSem;               VOID            *taskMux;               VOID            *taskEvent;             UINTPTR         args[4];                CHAR            taskName[OS_TCB_NAME_LEN];     LOS_DL_LIST     pendList;               LOS_DL_LIST     threadList;             SortLinkList    sortList;               UINT32          eventMask;              UINT32          eventMode;              UINT32          priBitMap;              INT32           errorNo;                UINT32          signal;                 sig_cb          sig;#if (LOSCFG_KERNEL_SMP == YES)    UINT16          currCpu;                UINT16          lastCpu;                UINT16          cpuAffiMask;            UINT32          timerCpu;           #if (LOSCFG_KERNEL_SMP_TASK_SYNC == YES)    UINT32          syncSignal;         #endif#if (LOSCFG_KERNEL_SMP_LOCKDEP == YES)    LockDep         lockDep;#endif#if (LOSCFG_KERNEL_SCHED_STATISTICS == YES)    SchedStat       schedStat;          #endif#endif    UINTPTR         userArea;    UINTPTR         userMapBase;    UINT32          userMapSize;            UINT32          processID;              FutexNode       futex;    LOS_DL_LIST     joinList;               LOS_DL_LIST     lockList;               UINT32          waitID;                 UINT16          waitFlag;           #if (LOSCFG_KERNEL_LITEIPC == YES)    UINT32          ipcStatus;    LOS_DL_LIST     msgListHead;    BOOL            accessMap[LOSCFG_BASE_CORE_TSK_LIMIT];#endif} LosTaskCB;

結構體LosTaskCB內容很多,各代表什麼含義?

LosTaskCB相當於任務在內核中的身份證,它反映出每個任務在生命周期內的運行情況。既然是周期就會有狀態,要運行就需要內存空間,就需要被內核算法調度,被選中CPU就去執行代碼段指令,CPU要執行就需要告訴它從哪裡開始執行,因為是多線程,但只有一個CPU就需要不斷的切換任務,那執行會被中斷,也需要再恢復後繼續執行,又如何保證恢復的任務執行不會出錯,這些問題都需要說明白。

Task怎麼管理


1、什麼是任務池?

前面已經說了任務是內核調度層面的概念,調度算法保證了task有序的執行,調度機制詳見其他姊妹篇的介紹。

如此多的任務怎麼管理和執行?管理靠任務池和就緒隊列,執行靠調度算法。
代碼如下(OsTaskInit):

LITE_OS_SEC_TEXT_INIT UINT32 OsTaskInit(VOID){       UINT32 index;    UINT32 ret;    UINT32 size;     g_taskMaxNum = LOSCFG_BASE_CORE_TSK_LIMIT;    size = (g_taskMaxNum + 1) * sizeof(LosTaskCB);        g_taskCBArray = (LosTaskCB *)LOS_MemAlloc(m_aucSysMem0, size);    if (g_taskCBArray == NULL) {           return LOS_ERRNO_TSK_NO_MEMORY;    }    (VOID)memset_s(g_taskCBArray, size, 0, size);     LOS_ListInit(&g_losFreeTask);    LOS_ListInit(&g_taskRecyleList);    for (index = 0; index < g_taskMaxNum; index++) {           g_taskCBArray[index].taskStatus = OS_TASK_STATUS_UNUSED;        g_taskCBArray[index].taskID = index;        LOS_ListTailInsert(&g_losFreeTask, &g_taskCBArray[index].pendList);    }     ret = OsPriQueueInit();    if (ret != LOS_OK) {           return LOS_ERRNO_TSK_NO_MEMORY;    }         for (index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) {           ret = OsSortLinkInit(&g_percpu[index].taskSortLink);        if (ret != LOS_OK) {               return LOS_ERRNO_TSK_NO_MEMORY;        }    }    return LOS_OK;}

g_taskCBArray 就是個任務池,默認創建128個任務,常駐內存,不被釋放。
g_losFreeTask 是空閒任務鍊表,想創建任務時來這裡申請一個空閒任務,用完了就回收掉,繼續給後面的申請使用。

g_taskRecyleList 是回收任務鍊表,專用來回收 exit 任務,任務所佔資源被確認歸還後被徹底刪除,就像員工離職一樣,得有個離職隊列和流程,要歸還電腦,郵箱,有沒有借錢要還的 等操作。

對應張大爺的故事:用戶要來場館領取表格填節目單,場館只準備了128張表格,領完就沒有了,但是節目表演完了會回收表格,這樣多了一張表格就可以給其他人領取了,這128張表格對應鴻蒙內核這就是任務池,簡單吧。

2、就緒隊列是怎麼回事

CPU 執行速度是很快的,鴻蒙內核默認一個時間片是 10ms, 資源有限,需要在眾多任務中來回的切換,所以絕不能讓 CPU 等待任務,CPU 就像公司最大的領導,下面很多的部門等領導來審批,吃飯。只有大家等領導,哪有領導等你們的道理,所以工作要提前準備好,每個部門的優先級又不一樣,所以每個部門都要有個任務隊列,裡面放的是領導能直接處理的任務,沒準備好的不要放進來,因為這是給 CPU 提前準備好的糧食!
這就是就緒隊列的原理,一共有32個就緒隊列,進程和線程都有,因為線程的優先級是默認32個, 每個隊列中放同等優先級的 task。
還是看源碼吧

#define OS_PRIORITY_QUEUE_NUM 32UINT32 OsPriQueueInit(VOID){       UINT32 priority;         g_priQueueList = (LOS_DL_LIST *)LOS_MemAlloc(m_aucSysMem0, (OS_PRIORITY_QUEUE_NUM * sizeof(LOS_DL_LIST)));    if (g_priQueueList == NULL) {           return LOS_NOK;    }     for (priority = 0; priority < OS_PRIORITY_QUEUE_NUM; ++priority) {           LOS_ListInit(&g_priQueueList[priority]);    }    return LOS_OK;}

注意看g_priQueueList 的內存分配,就是32個LOS_DL_LIST,還記得 LOS_DL_LIST 的妙用嗎,不清楚的去 鴻蒙系統源碼分析(總目錄) 裡面翻。

對應張大爺的故事:就是門口那些排隊的都是至少有一個節目單是符合表演標準的,資源都到位了,沒有的連排隊的資格都木有,就慢慢等吧。

3、任務棧是怎麼回事

每個任務都是獨立開的,任務之間也相互獨立,之間通訊通過 IPC,這裡的「獨立」指的是每個任務都有自己的運行環境 —— 棧空間,稱為任務棧,棧空間裡保存的信息包含局部變量、寄存器、函數參數、函數返回地址等等
但系統中只有一個 CPU,任務又是獨立的,調度的本質就是 CPU 執行一個新 task,老 task 在什麼地方被中斷誰也不清楚,是隨機的。那如何保證老任務被再次調度選中時還能從上次被中斷的地方繼續玩下去呢?

答案是:任務上下文,CPU 內有一堆的寄存器,CPU 運行本質的就是這些寄存器的值不斷的變化,只要切換時把這些值保存起來,再還原回去就能保證 task 的連續執行,讓用戶毫無感知。鴻蒙內核給一個任務執行的時間是 20ms ,也就是說有多任務競爭的情況下,一秒鐘內最多要來回切換50次。

對應張大爺的故事:就是碰到節目沒有表演完就必須打斷的情況下,需要把當時的情況記錄下來,比如小朋友在演躲貓貓的遊戲,一半不演了,張三正在樹上,李四正在廁所躲,都記錄下來,下次再回來你們上次在哪就會哪呆著去,就位了繼續表演。這樣就接上了,觀眾就木有感覺了。

任務上下文(TaskContext)是怎樣的呢?還是直接看源碼

typedef struct {   #if !defined(LOSCFG_ARCH_FPU_DISABLE)    UINT64 D[FP_REGS_NUM];     UINT32 regFPSCR;           UINT32 regFPEXC;       #endif    UINT32 resved;              UINT32 regPSR;    UINT32 R[GEN_REGS_NUM];     UINT32 SP;                  UINT32 LR;                  UINT32 PC;              } TaskContext;

發現基本都是CPU寄存器的恢復現場值, 具體各寄存器有什麼作用大家可以去網上詳查,後續也有專門的文章來介紹。這裡說其中的三個寄存器 SP, LR, PC

LR
用途有二,一是保存子程序返回地址,當調用BL、BX、BLX等跳轉指令時會自動保存返回地址到LR;二是保存異常發生的異常返回地址。

PC(Program Counter)
為程序計數器,用於保存程序的執行地址,在ARM的三級流水線架構中,程序流水線包括取址、解碼和執行三個階段,PC指向的是當前取址的程序地址,所以32位ARM中,解碼地址(正在解析還未執行的程序)為PC-4,執行地址(當前正在執行的程序地址)為PC-8, 當突然發生中斷的時候,保存的是PC的地址。

SP
每一種異常模式都有其自己獨立的r13,它通常指向異常模式所專用的堆棧,當ARM進入異常模式的時候,程序就可以把一般通用寄存器壓入堆棧,返回時再出棧,保證了各種模式下程序的狀態的完整性。

4、任務棧初始化

任務棧的初始化就是任務上下文的初始化,因為任務沒開始執行,裡面除了上下文不會有其他內容,注意上下文存放的位置在棧的底部。

Task函數集


LITE_OS_SEC_TEXT_INIT VOID *OsTaskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack, BOOL initFlag){       UINT32 index = 1;    TaskContext *taskContext = NULL;     if (initFlag == TRUE) {           OsStackInit(topStack, stackSize);    }    taskContext = (TaskContext *)(((UINTPTR)topStack + stackSize) - sizeof(TaskContext));         taskContext->PC = (UINTPTR)OsTaskEntrySetupLoopFrame;    taskContext->PC = (UINTPTR)OsTaskEntry;    taskContext->LR = (UINTPTR)OsTaskExit;      taskContext->resved = 0x0;    taskContext->R[0] = taskID;                 taskContext->R[index++] = 0x01010101;       for (; index < GEN_REGS_NUM; index++) {           taskContext->R[index] = taskContext->R[index - 1] + taskContext->R[1];     }     taskContext->regPSR = PSR_MODE_SVC_THUMB;     taskContext->regPSR = PSR_MODE_SVC_ARM;            for (index = 0; index < FP_REGS_NUM; index++) {           taskContext->D[index] = 0xAAA0000000000000LL + index;     }    taskContext->regFPSCR = 0;    taskContext->regFPEXC = FP_EN;     return (VOID *)taskContext;}

1、使用場景和功能

任務創建後,內核可以執行鎖任務調度,解鎖任務調度,掛起,恢復,延時等操作,同時也可以設置任務優先級,獲取任務優先級。任務結束的時候,則進行當前任務自刪除操作。

Huawei LiteOS 系統中的任務管理模塊為用戶提供下面幾種功能。

功能分類接口名描述任務的創建和刪除LOS_TaskCreateOnly創建任務,並使該任務進入suspend狀態,並不調度。
LOS_TaskCreate創建任務,並使該任務進入ready狀態,並調度。
LOS_TaskDelete刪除指定的任務。任務狀態控制LOS_TaskResume恢復掛起的任務。
LOS_TaskSuspend掛起指定的任務。
LOS_TaskDelay任務延時等待。
LOS_TaskYield顯式放權,調整指定優先級的任務調度順序。任務調度的控制LOS_TaskLock鎖任務調度。
LOS_TaskUnlock解鎖任務調度。任務優先級的控制LOS_CurTaskPriSet設置當前任務的優先級。
LOS_TaskPriSet設置指定任務的優先級。
LOS_TaskPriGet獲取指定任務的優先級。任務信息獲取LOS_CurTaskIDGet獲取當前任務的ID。
LOS_TaskInfoGet設置指定任務的優先級。
LOS_TaskPriGet獲取指定任務的信息。
LOS_TaskStatusGet獲取指定任務的狀態。
LOS_TaskNameGet獲取指定任務的名稱。
LOS_TaskInfoMonitor監控所有任務,獲取所有任務的信息。
LOS_NextTaskIDGet獲取即將被調度的任務的ID。2、創建任務的過程

創建任務之前先了解另一個結構體 tagTskInitParam

typedef struct tagTskInitParam {       TSK_ENTRY_FUNC  pfnTaskEntry;      UINT16          usTaskPrio;        UINT16          policy;            UINTPTR         auwArgs[4];        UINT32          uwStackSize;       CHAR            *pcName;       #if (LOSCFG_KERNEL_SMP == YES)    UINT16          usCpuAffiMask; #endif    UINT32          uwResved;          UINT16          consoleID;         UINT32          processID;    UserTaskParam   userParam;} TSK_INIT_PARAM_S;

這些初始化參數是外露的任務初始參數,pfnTaskEntry 對java來說就是你new進程的run(),需要上層使用者提供。

看個例子吧:shell中敲 ping 命令看下它創建的過程

u32_t osShellPing(int argc, const char **argv){       int ret;    u32_t i = 0;    u32_t count = 0;    int count_set = 0;    u32_t interval = 1000;     u32_t data_len = 48;     ip4_addr_t dst_ipaddr;    TSK_INIT_PARAM_S stPingTask;            if (count == 0 || count > LWIP_SHELL_CMD_PING_RETRY_TIMES) {           if (ping_taskid > 0) {               PRINTK("Ping task already running and only support one now\n");            return LOS_NOK;        }        stPingTask.pfnTaskEntry = (TSK_ENTRY_FUNC)ping_cmd;        stPingTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;        stPingTask.pcName = "ping_task";        stPingTask.usTaskPrio = 8;          stPingTask.uwResved = LOS_TASK_STATUS_DETACHED;        stPingTask.auwArgs[0] = dst_ipaddr.addr;         stPingTask.auwArgs[1] = count;        stPingTask.auwArgs[2] = interval;        stPingTask.auwArgs[3] = data_len;        ret = LOS_TaskCreate((UINT32 *)(&ping_taskid), &stPingTask);    }      return LOS_OK;ping_error:    lwip_ping_usage();    return LOS_NOK;}

發現ping的調度優先級是8,比shell 還高,那shell的是多少?答案是:看源碼是 9

LITE_OS_SEC_TEXT_MINOR UINT32 ShellTaskInit(ShellCB *shellCB){       CHAR *name = NULL;    TSK_INIT_PARAM_S initParam = {   0};    if (shellCB->consoleID == CONSOLE_SERIAL) {           name = SERIAL_SHELL_TASK_NAME;    } else if (shellCB->consoleID == CONSOLE_TELNET) {           name = TELNET_SHELL_TASK_NAME;    } else {           return LOS_NOK;    }    initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)ShellTask;    initParam.usTaskPrio   = 9;     initParam.auwArgs[0]   = (UINTPTR)shellCB;    initParam.uwStackSize  = 0x3000;    initParam.pcName       = name;    initParam.uwResved     = LOS_TASK_STATUS_DETACHED;    (VOID)LOS_EventInit(&shellCB->shellEvent);    return LOS_TaskCreate(&shellCB->shellTaskHandle, &initParam);}

關於shell後續會詳細介紹,請持續關注。

前置條件了解清楚後,具體看任務是如何一步步創建的,如何和進程綁定,加入調度就緒隊列,還是繼續看源碼

LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *initParam){    UINT32 ret;    UINT32 intSave;    LosTaskCB *taskCB = NULL;     if (initParam == NULL) {        return LOS_ERRNO_TSK_PTR_NULL;    }     if (OS_INT_ACTIVE) {        return LOS_ERRNO_TSK_YIELD_IN_INT;    }     if (initParam->uwResved & OS_TASK_FLAG_IDLEFLAG) {        initParam->processID = OsGetIdleProcessID();    } else if (OsProcessIsUserMode(OsCurrProcessGet())) {        initParam->processID = OsGetKernelInitProcessID();    } else {        initParam->processID = OsCurrProcessGet()->processID;    }    initParam->uwResved &= ~OS_TASK_FLAG_IDLEFLAG;    initParam->uwResved &= ~OS_TASK_FLAG_PTHREAD_JOIN;    if (initParam->uwResved & LOS_TASK_STATUS_DETACHED) {        initParam->uwResved = OS_TASK_FLAG_DETACHED;    }     ret = LOS_TaskCreateOnly(taskID, initParam);    if (ret != LOS_OK) {        return ret;    }    taskCB = OS_TCB_FROM_TID(*taskID);     SCHEDULER_LOCK(intSave);    taskCB->taskStatus &= ~OS_TASK_STATUS_INIT;    OS_TASK_SCHED_QUEUE_ENQUEUE(taskCB, 0);    SCHEDULER_UNLOCK(intSave);         LOS_MpSchedule(OS_MP_CPU_ALL);    if (OS_SCHEDULER_ACTIVE) {        LOS_Schedule();    }     return LOS_OK;}

對應張大爺的故事:就是節目單要怎麼填,按格式來,從哪裡開始演,要多大的空間,王場館好協調好現場的環境。這裡注意 在同一個節目單只要節目沒演完,王場館申請場地的空間就不能給別人用,這個場地空間對應的就是鴻蒙任務的棧空間,除非整個節目單都完了,就回收了。把整個場地乾乾淨淨的留給下一個人的節目單來表演。

至此的創建已經完成,已各就各位,源碼最後還申請了一次LOS_Schedule();因為鴻蒙的調度方式是搶佔式的,如何本次task的任務優先級高於其他就緒隊列,那麼接下來要執行的任務就是它了!

3、Task/線程部分還有哪些重要內容沒講到?

內存怎麼分配的,線程之間怎麼通訊,運行期間堆棧是怎麼執行的,等後續講內存,IPC部分再拆開來分析。

原文地址:https://blog.csdn.net/kuangyufei/article/details/108621428


更多精彩推薦

☞為什麼雲原生+分布式是資料庫的未來?

☞Swift、Flutter 共同瞄準 Windows!

☞不是「老賴」是「真還」!羅永浩 6 億債務還了 4 億

☞雲原生安全模型與實踐

☞可租賃、可定製的虛擬人居然還能這麼玩?9月25日來百度大腦人像特效專場一探究竟!

☞區塊鏈+生鮮:杜絕「偷梁換柱」和「以次充好」

相關焦點

  • 鴻蒙內核源碼分析:調度機制篇
    狹義上的後續有 鴻蒙內核源碼分析(啟動過程篇) 來說明。不知道大家有沒有這種體會,學一個東西的過程中要接觸很多新概念,尤其像 Java/android 的生態,概念賊多,很多同學都被繞在概念中出不來,痛苦不堪。那問題是為什麼需要這麼多的概念呢?舉個例子就明白了:假如您去深圳參加一個面試老闆問你哪裡人?你會說是江西人,湖南人...
  • 鴻蒙內核源碼分析(自旋鎖篇) | 彙編到令人心碎的自旋鎖 | 中文註解HarmonyOS源碼 | v26.01
    百萬漢字註解 >> 精讀內核源碼,中文註解分析, 深挖地基工程,大腦永久記憶, 四大碼倉每日同步更新百篇博客分析 >
  • 鴻蒙內核源碼分析(內存主奴篇) | 紫禁城的主子和奴才如何相處? | 中文註解HarmonyOS源碼 | v9.03
    鴻蒙內核源碼注釋中文版 【 Gitee倉 | CSDN倉 | Github倉 | Coding倉 】精讀內核源碼,中文註解分析.深挖地基工程,構建底層網圖
  • Java8線程池ThreadPoolExecutor底層原理及其源碼解析
    ()<maximumPoolSize, 就創建一個臨時線程處理task.當workers.size()大於corePoolSize時, 並且workQueue已經滿了, 但是workers.size()>=maximumPoolSize, 執行拒絕策略.後續會有對ThreadPoolExecutor#execute方法的詳細解讀: execute方法源碼: 提交task到線程池.
  • Linux內核獲取當前進程結構的current宏
    Linux內核的源碼結構簡介(1)簡單介紹了Linux內核源碼的目錄結構,以及和進程的task_struct的幾個關鍵變量,最後提到了在內核裡獲取當前進程的pid的代碼:current->pid。
  • 是不是看不懂鴻蒙代碼?有人給你寫好中文注釋你看不看?
    每個碼農,職業生涯,都應精讀一遍內核源碼. 鴻蒙內核源碼就是很好的精讀項目.一旦熟悉內核代碼的實現,將迅速拔高對計算機整體理解,從此高屋建瓴看問題.但9月10日鴻蒙正式開源,重新激活了注者多年的心願,就有那麼點一發不可收拾了 :|P致敬鴻蒙內核開發者感謝開放原子開源基金會,鴻蒙內核開發者提供了如此優秀的源碼,了了多年的夙願,津津樂道於此.越深入精讀內核源碼,越能感受到設計者的精巧用心,創新突破. 向開發者致敬.
  • 三萬字總結最全Java線程池源碼面試題
    然後,通過分析ThreadPoolExecutor的execute和addWorker兩個核心方法;學習如何把任務線程加入到線程池中運行.第6個參數: threadFactory 表示線程工廠它用來生產一組相同任務的線程;線程池的命名是通過給這個factory增加組名前綴來實現的.在虛擬機棧分析時,就可以知道線程任務是由哪個線程工廠產生的.
  • 「原創」Java並發編程系列36|FutureTask
    本文轉載自【微信公眾號:java進階架構師,ID:java_jiagoushi】經微信公眾號授權轉載,如需轉載與原文作者聯繫線程池源碼中出現了很多Callable、Future、FutureTask等以前沒介紹過的接口,尤其是線程池提交任務時總是把任務封裝成FutureTask,今天就來為大家解惑:
  • 剛剛用鴻蒙跑了個「hello world」!跑通後,我特麼開始懷疑人生....
    關於鴻蒙的教程其實網上也已經有一些嘗鮮的小夥伴分享的相關文章了,編者我按照步驟一步步跑下來,整個流程還是非常簡單的,尤其是對Android開發的小夥伴來說,從IDE到項目的創建及項目的編譯安裝簡直是一模一樣呀。我特麼的都有點懷疑人生了...感興趣的讀者也可以試試哦。再貼一下鴻蒙的源碼地址:https://openharmony.gitee.com
  • 一文講透 「進程、線程、協程」
    (python的多線程是偽多線程,下文中將詳細介紹)什麼是協程協程(Coroutine,又稱微線程)是一種比線程更加輕量級的存在,協程不是被作業系統內核所管理,而完全是由程序所控制。協程與線程以及進程的關係見下圖所示。
  • 華為鴻蒙OS正式發布:可用於手機,基於微內核,寓意開天闢地
    今天,華為開發者大會正式舉辦,華為消費者業務CEO餘承東在會上正式推出基於微內核的全場景分布式OS「鴻蒙」。  根據餘承東的說法,安卓有超過1億行代碼,內核就超過2000萬行,但一般用戶用到的代碼不到8%,整體比較冗餘,在IoT時代這既沒必要也不需要。  由此他提出了「微內核」的概念,也是鴻蒙OS的特點之一。區別於「宏內核」,微內核採用同一套操作平臺,針對不同硬體能力的產品進行部署,並採用分布式架構,提升效率。
  • LockSupport:一個很靈活的線程工具類
    用於線程監控和分析工具來定位原因的。現在我們知道了LockSupport是用來阻塞和喚醒線程的,而且之前相信我們都知道wait/notify也是用來阻塞和喚醒線程的,那和它相比,LockSupport有什麼優點呢?這裡假設你已經了解了wait/notify的機制,如果不了解,可以在網上一搜,很簡單。
  • 鴻蒙和安卓,到底有什麼區別?
    在開發者大會上宣布將 HarmonyOS原始碼捐贈給中國開放原子開源基金會,並在大會上公布了鴻蒙系統的開源路線。https://openharmony.gitee.com/openharmony鴻蒙使用基於 Intellij IDEA 深度定製研發的 DevEco Studio 作為其開發工具。
  • 鴻蒙系統初探-之從舊版鴻蒙彈窗說起
    分析Android 此彈窗邏輯分析:在 AppWarnings 中 onStartActivity中會根據系統支持的版本進行判斷:package com.android.server.wm請嘗試檢查更新或與開發者聯繫鴻蒙彈窗分析鴻蒙應用安裝包格式這裡有一點需要大家清楚的是,鴻蒙系統之所以會彈出這個彈窗,很重要的一點就是, 直接給鴻蒙系統安裝的.apk文件,而.apk是安卓安裝包的格式,那鴻蒙系統的默認的安裝包格式默認也是.apk嗎?答案是no。
  • java多線程中sleep和wait的4個區別,你知道幾個?
    sleep和wait的區別是面試中一個非常常見的問題,因為從表象來看,好像sleep和wait都能使線程處於阻塞狀態,但是卻有著本質上的卻別。這篇文章就來好好分析一下。整體的區別其實是有四個:1、sleep是線程中的方法,但是wait是Object中的方法。
  • 鴻蒙OS科普文
    以及發布會提及最多是他的萬物互連,全場景,分布式,微內核,軟總線。換句話說,鴻蒙OS 是為全場景,分布式設計的,微內核,軟總線是他重要的實現。對於全場景,分布式理解,我們可以想一下華為自家的多屏協作,以及電腦,平板和手機可以很方便實現在電腦上操作平板,手機。
  • 微博某業務資料庫連續兩次oom問題分析
    環境第一次OOM,內核compact【分析過程】先是收到B從庫的連接數報警,B從庫的連接數從日常的4K漲到10K+,而A從庫最低僅2K那究竟是什麼原因觸發內核進行這個操作的呢?我們需要進一步研究內核compaction算法。簡單來說,可以理解為做的事情是重組內存中碎片,目的是整理出更大的物理上連續的區域。觸發的原因會有以下原因:(可移動的內存為用戶程序訪問的物理內存,對應不可移動的為內核在使用的物理內存.)原理如圖:
  • 鴻蒙作業系統是個啥,牛不牛? | 餘興鎬
    、微內核、可信安全、模塊化解耦、可彈性部署、跨生態共享、賦能、萬物互聯……大多數觀眾還是不明覺厲,所以鴻蒙作業系統到底牛不牛逼?按官方說法,鴻蒙是基於微內核的全場景分布式OS。那個……微內核的全場景分布式OS又是什麼啊?
  • Windows XP源碼洩露丨大東話安全
    源碼是在哪裡洩露的?洩露的內容裡都有什麼?大東:別著急,我先回答你的第一個問題吧,事件起源於論壇,前幾天4chan 論壇的一名用戶發帖稱 Windows XP 源碼已被洩露,並在帖子裡面附上了一張正在解壓 Windows NT 內核源碼的截圖。