自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

深入探究 Linux 線程創(chuàng)建:glibc 的 pthread_create 與神秘的 clone 函數(shù)

系統(tǒng) Linux
在Linux下進(jìn)行多線程編程時(shí),我們通常會(huì)使用POSIX線程庫(kù)(pthread),它提供了一組用于線程管理的API函數(shù),其中最常用的就是pthread_create函數(shù)。

在Linux下進(jìn)行多線程編程時(shí),我們通常會(huì)使用POSIX線程庫(kù)(pthread),它提供了一組用于線程管理的API函數(shù),其中最常用的就是pthread_create函數(shù)。不過(guò),了解pthread_create的內(nèi)部工作原理和底層系統(tǒng)調(diào)用對(duì)于深入理解Linux多線程編程非常重要。

clone與fork

pthread_create函數(shù)是glibc中實(shí)現(xiàn)的POSIX線程庫(kù)的一部分,它是基于Linux系統(tǒng)調(diào)用clone來(lái)創(chuàng)建線程的。clone函數(shù)是一個(gè)比f(wàn)ork更靈活和底層的系統(tǒng)調(diào)用,它允許我們創(chuàng)建一個(gè)新的進(jìn)程或線程,而fork只能創(chuàng)建新進(jìn)程。

clone函數(shù)和fork函數(shù)都用于創(chuàng)建新的執(zhí)行流,但它們有一些重要的區(qū)別:

(1) 創(chuàng)建級(jí)別:

  • fork函數(shù)用于創(chuàng)建一個(gè)新的進(jìn)程,新進(jìn)程是調(diào)用進(jìn)程的副本。
  • clone函數(shù)可以用于創(chuàng)建新的線程或新的進(jìn)程,取決于傳遞給它的標(biāo)志。這使clone比f(wàn)ork更加靈活。

(2) 共享資源:

  • fork創(chuàng)建的進(jìn)程有獨(dú)立的地址空間,父子進(jìn)程之間不共享內(nèi)存。
  • clone可以選擇與父進(jìn)程共享內(nèi)存、文件描述符等資源,這可以用于創(chuàng)建線程。

(3) 系統(tǒng)開(kāi)銷:

  • 由于fork會(huì)復(fù)制整個(gè)地址空間,因此開(kāi)銷較大。
  • clone可以選擇共享資源,因此通常比f(wàn)ork更高效。   

clone函數(shù)的實(shí)現(xiàn)原理

clone函數(shù)通過(guò)傳遞不同的標(biāo)志參數(shù)來(lái)控制其行為。以下是一些常見(jiàn)的標(biāo)志參數(shù)及其作用:

  • CLONE_VM:共享虛擬內(nèi)存,子進(jìn)程/線程與父進(jìn)程共享地址空間。
  • CLONE_FS:共享文件系統(tǒng)信息,子進(jìn)程/線程與父進(jìn)程共享文件系統(tǒng)。
  • CLONE_FILES:共享文件描述符表,子進(jìn)程/線程與父進(jìn)程共享打開(kāi)的文件。
  • CLONE_SIGHAND:共享信號(hào)處理,子進(jìn)程/線程與父進(jìn)程共享信號(hào)處理器表。
  • CLONE_PARENT_SETTID:設(shè)置父進(jìn)程的TID(線程ID)。
  • CLONE_CHILD_SETTID:設(shè)置子進(jìn)程/線程的TID。

clone函數(shù)的核心思想是在新的執(zhí)行流中執(zhí)行一個(gè)新的函數(shù),這個(gè)函數(shù)通常是main函數(shù)的替代品。這個(gè)新函數(shù)在創(chuàng)建線程時(shí)會(huì)被調(diào)用,它可以執(zhí)行不同的任務(wù),使得多線程編程成為可能。

clone函數(shù)創(chuàng)建線程示例

要使用clone函數(shù)創(chuàng)建線程,我們需要傳遞適當(dāng)?shù)臉?biāo)志參數(shù)和一個(gè)函數(shù)指針,該函數(shù)指針指向線程要執(zhí)行的函數(shù)。以下是一個(gè)簡(jiǎn)單的示例:

#define _GNU_SOURCE
#include <stdio.h>
#include <sched.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

#define STACK_SIZE (1024 * 1024)

void *child_function(void *arg) {
    printf("Child thread: PID=%d, TID=%ld\n", getpid(), syscall(SYS_gettid));
    return NULL;
}

int main() {
    char *stack;
    char *stack_top;
    pid_t pid;

    stack = (char *)malloc(STACK_SIZE);
    if (stack == NULL) {
        perror("malloc");
        exit(EXIT_FAILURE);
    }

    stack_top = stack + STACK_SIZE;

    pid = clone(child_function, stack_top, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, NULL);
    if (pid == -1) {
        perror("clone");
        exit(EXIT_FAILURE);
    }

    printf("Parent thread: PID=%d, TID=%ld, Child PID=%d\n", getpid(), syscall(SYS_gettid), pid);

    // Wait for the child to finish
    if (waitpid(pid, NULL, 0) == -1) {
        perror("waitpid");
        exit(EXIT_FAILURE);
    }

    free(stack);
    return 0;
}

這個(gè)示例中,我們使用clone函數(shù)創(chuàng)建了一個(gè)新線程,新線程將執(zhí)行child_function函數(shù)。父線程和子線程可以共享虛擬內(nèi)存、文件系統(tǒng)信息等資源,這使得它們可以方便地共享數(shù)據(jù)。

責(zé)任編輯:趙寧寧 來(lái)源: 囧囧妹
相關(guān)推薦

2021-06-17 07:55:34

線程進(jìn)程COW

2023-11-24 11:24:16

Linux系統(tǒng)

2024-08-26 00:00:01

C#線程操作系統(tǒng)

2009-12-09 10:07:19

Linux靜態(tài)路由

2025-02-27 00:32:35

2009-11-27 10:37:41

GPRS路由

2023-11-23 12:36:22

Linux多線程

2021-07-08 09:48:01

NodeBuffer亂碼

2009-12-09 13:35:09

靜態(tài)路由配置

2009-11-20 09:56:27

軟交換路由技術(shù)

2023-10-19 08:30:58

線程源碼thread

2024-01-29 16:47:44

函數(shù)封裝開(kāi)發(fā)

2025-01-02 14:50:34

MyBatis開(kāi)發(fā)緩存

2023-06-27 08:37:35

Java反射動(dòng)態(tài)代理機(jī)制

2023-11-17 08:02:34

系統(tǒng)調(diào)用linux

2010-09-30 09:16:04

cookieJ2ME

2009-12-08 17:24:30

路由器配置

2011-06-22 13:57:54

Java多線程

2011-06-22 13:47:16

Java多線程

2022-02-23 16:49:19

Linux內(nèi)存數(shù)據(jù)結(jié)構(gòu)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)