news 2026/5/10 3:29:24

DAY32 Linux Thread Programming

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DAY32 Linux Thread Programming

Linux Thread Programming

I. Core Theoretical Foundations of Threads

1. What is a Thread?

  • Definition: A thread is an execution unit within a process, also referred to as a “Lightweight Process (LWP)”. It belongs to a specific process and shares the process’s resources (code segment, data segment, file descriptors, etc.).
  • Core Purpose: Enable concurrent execution by splitting time-consuming tasks into multiple threads for parallel processing, thereby improving program efficiency (e.g., video rendering, concurrent network requests).

2. Core Characteristics of Threads

CharacteristicExplanation
Resource AllocationProcesses are the system’s smallest unit of resource allocation; threads do not have independent resources (share process resources).
Execution UnitThreads are the system’s smallest unit of execution and the basic object of CPU scheduling.
Hierarchical RelationshipThreads within a process are peer-to-peer; a “main thread” (the thread where themainfunction runs) exists by default.
Resource SharingThreads share the process’s global variables, static variables, file descriptors, etc.; only the stack area (8MB) is independent.
StabilityThreads are unstable: a single thread crash will cause the entire process to exit; processes are relatively stable and isolated from each other.
Creation OverheadThread creation only requires allocating an independent stack area (8MB), while process creation requires allocating a 3GB virtual address space (much higher overhead).
Concurrency EfficiencyThreads have higher concurrency than processes; switching between threads within the same process does not require address space switching, resulting in higher efficiency.

3. Core Differences Between Threads and Processes

Comparison DimensionThreadProcess
Resource AllocationShares resources of the parent process; no independent address space.Has an independent address space and independent resources (code segment, data segment, etc.).
Creation/Switching OverheadLow (only stack area allocation).High (full address space allocation).
Communication MethodDirectly access shared variables; simple communication.Requires IPC (pipes, message queues, etc.); complex communication.
StabilityLow (thread crash leads to process exit).High (processes are isolated from each other).
Concurrency EfficiencyHigh (thread switching without address space switching).Low (high process switching overhead).

4. Core Workflow of Thread Programming (POSIX Standard)

  1. Create Multiple Threads: Usepthread_createto create child threads and specify the thread execution function.
  2. Thread Task Execution: Child threads complete specific tasks (resource operations, computations, etc.) in the callback function.
  3. Thread Resource Recycling: Release thread resources usingpthread_join(blocking recycling) orpthread_detach(automatic recycling) to avoid memory leaks.

5. Detailed Explanation of Key Thread Functions

The POSIX thread library (libpthread) provides core interfaces for thread operations. Below are explanations of commonly used functions:

Function PrototypeFunction Description
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)Creates a child thread.
-thread: Output parameter to store the new thread ID.
-attr: Thread attributes (useNULLfor default).
-start_routine: Thread callback function (execution entry).
-arg: Parameter for the callback function.
- Return value:0on success; error code on failure.
pthread_t pthread_self(void)Gets the current thread ID.
- Return value: ID of the current thread (typeunsigned long, use%lufor printing).
void pthread_exit(void *retval)Child thread exits actively.
-retval: Exit status of the thread (returned to the main thread).
int pthread_cancel(pthread_t thread)Main thread cancels a specified child thread.
-thread: Target thread ID.
- Return value:0on success; error code on failure.
int pthread_join(pthread_t thread, void **retval)Blocks to recycle child thread resources.
-thread: ID of the thread to recycle.
-retval: Receives the exit status of the child thread.
- Return value:0on success; error code on failure.
int pthread_detach(pthread_t thread)Sets the thread detach attribute (resources are automatically recycled after exit).
- No need for the main thread to callpthread_join.

6. Thread Viewing Commands

# View all threads in the system (PID: Process ID, LWP: Thread ID, COMM: Thread name)ps-eLo pid,ppid,lwp,stat,comm# View detailed thread information (including CPU usage, memory, etc.)ps-eLf

II. Practical Code Analysis (8 Core Examples)

The following 8 practical code examples, from basic to advanced, will help you gradually master thread programming skills (all code must be compiled with thepthreadlibrary:gcc filename.c -o filename -lpthread).

Example 01: Create Multiple Threads (01pthread.c)

Function: Create 2 child threads to execute different tasks (sending videos, receiving controls)
#include<stdio.h>#include<pthread.h>#include<stdlib.h>#include<unistd.h>#include<string.h>// Thread 1 callback function: Send videovoid*thread_function(void*arg){while(1){printf("Sending video...\n");sleep(1);// Execute every 1 second}returnNULL;}// Thread 2 callback function: Receive controlvoid*thread_function2(void*arg){while(1){printf("Receiving control...\n");sleep(1);}returnNULL;}intmain(){pthread_tthread_id;// Thread 1 IDpthread_tthread_id2;// Thread 2 ID// Create thread 1pthread_create(&thread_id,NULL,thread_function,NULL);// Create thread 2pthread_create(&thread_id2,NULL,thread_function2,NULL);// Main thread blocks (prevents main thread exit from terminating child threads)while(1){sleep(1);}return0;}
Key Notes:
  1. pthread_createparameters: Thread ID pointer, default attributes (NULL), callback function, callback function parameter (NULL).
  2. The main thread must remain running (while(1)); otherwise, the entire process terminates after the main thread exits, and child threads are destroyed.
  3. Compilation command:gcc 01pthread.c -o 01pthread -lpthread.
  4. Running result: The two child threads alternately output “Sending video…” and “Receiving control…”, achieving concurrent execution.

Example 02: Get Thread ID (02pthread_self.c)

Function: Get the IDs of the main thread and child threads usingpthread_self()
#include<stdio.h>#include<pthread.h>#include<unistd.h>#include<stdlib.h>#include<string.h>void*th1(void*arg){while(1){// Print child thread 1 ID (%lu corresponds to unsigned long type)printf("Sending video...tid:%lu\n",pthread_self());sleep(1);}returnNULL;}void*th2(void*arg){while(1){printf("Receiving control...tid:%lu\n",pthread_self());sleep(1);}returnNULL;}intmain(){pthread_ttid1,tid2;pthread_create(&tid1,NULL,th1,NULL);pthread_create(&tid2,NULL,th2,NULL);// Print main thread IDwhile(1){printf("main tid:%lu\n",pthread_self());sleep(1);}return0;}
Key Notes:
  1. pthread_self()has no parameters and returns the ID of the current thread (typepthread_t, recommended to use%lufor formatted output).
  2. Running result: The main thread and two child threads output their respective IDs. You can verify the existence of threads usingps -eLo lwp,comm.

Example 03: Thread Exit (03pthread_exit.c)

Function: The child thread exits actively usingpthread_exit(), and the main thread exits after running a specified number of times
#include<stdio.h>#include<pthread.h>#include<stdlib.h>#include<unistd.h>#include<string.h>void*th(void*arg){while(1){printf("sub_th %lu\n",pthread_self());sleep(1);}pthread_exit(NULL);// Child thread exits actively (unreachable here due to while(1), for demonstration only)}intmain(){pthread_ttid;pthread_create(&tid,NULL,th,NULL);inti=8;// Main thread exits after running for 8 secondswhile(i--){printf("main_th %lu\n",pthread_self());sleep(1);}return0;}
Key Notes:
  1. pthread_exit(NULL): The child thread exits actively, with the parameter being the exit status (NULLmeans no return value).
  2. Note: After the main thread exits, child threads are forcibly terminated (even if the child thread haswhile(1)).
  3. Running result: The main thread outputs 8 times and exits, and the child thread terminates simultaneously.

Example 04: Cancel Thread (04phread_cancel.c)

Function: The main thread cancels a child thread usingpthread_cancel()
#include<stdio.h>#include<stdlib.h>#include<pthread.h>#include<unistd.h>#include<string.h>void*thread_func(void*arg){while(1){printf("subth %lu\n",pthread_self());sleep(1);}}intmain(){pthread_ttid;pthread_create(&tid,NULL,thread_func,NULL);inti=0;while(1){printf("main th %lu\n",pthread_self());sleep(1);i++;if(i==2){// Cancel the child thread after running for 2 secondspthread_cancel(tid);printf("Child thread canceled\n");}}return0;}
Key Notes:
  1. pthread_cancel(tid): Sends a cancellation request to the specified child thread, which responds at a “cancellation point” (e.g., system calls likesleeporprintf).
  2. Running result: The child thread outputs twice and is canceled, while the main thread continues running.
  3. Note:pthread_cancelonly sends a request. If the child thread has no cancellation points (e.g., a pure computation loop), you need to manually callpthread_testcancel()to set a cancellation point.

Example 05: Thread Resource Recycling (05pthread_jion.c)

Function: The main thread blocks to wait for the child thread to complete and recycles resources usingpthread_join()
#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<string.h>#include<pthread.h>void*th(void*arg){inti=5;while(i--){printf("workth,%lu\n",pthread_self());sleep(1);}returnNULL;}intmain(intargc,char**argv){pthread_ttid;pthread_create(&tid,NULL,th,NULL);// Block to wait for the child thread tid to complete and recycle its resourcespthread_join(tid,NULL);printf("Child thread finished, main thread exiting\n");return0;}
Key Notes:
  1. pthread_join(tid, NULL): The main thread blocks until the child threadtidexits, preventing the child thread from becoming a “zombie thread” (unrecycled resources).
  2. The second parameter isNULL, indicating no interest in the child thread’s exit status.
  3. Running result: The child thread outputs 5 times and exits, and the main thread prints a message and exits.

Example 06: Get Thread Return Value (06pthread_jionret.c)

Function: The child thread dynamically allocates memory and returns data; the main thread gets the return value and frees the memory usingpthread_join()
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<pthread.h>#include<unistd.h>void*th(void*arg){// Dynamically allocate memory (stack data of the child thread cannot be returned, as it is released when the thread exits)char*str=(char*)malloc(20);strcpy(str,"I'm exiting");returnstr;// Return the dynamically allocated memory address}intmain(intargc,char*argv[]){pthread_ttid;pthread_create(&tid,NULL,th,NULL);void*ret=NULL;// Recycle the child thread and get the return value (ret points to the memory allocated by the child thread)pthread_join(tid,&ret);printf("Child thread return value: %s\n",(char*)ret);free(ret);// Free the memory allocated by the child thread to avoid memory leaksreturn0;}
Key Notes:
  1. The child thread’s return value cannot be a stack variable (the stack is released when the thread exits); usemallocfor dynamic memory allocation.
  2. The main thread receives the return value through the second parameter&retofpthread_joinand must manuallyfreeit after use.
  3. Running result: The main thread prints the string “I’m exiting” returned by the child thread.

Example 07: Pass Struct Parameters (07.c)

Function: The main thread passes struct parameters to the child thread; the child thread prints and returns the struct address
#include<stdio.h>#include<pthread.h>#include<stdlib.h>#include<unistd.h>#include<string.h>// Define a struct (store user information)typedefstruct{charname[20];intage;charaddress[50];}PER;void*th(void*arg){// Convert void* type to struct pointerPER*p=(PER*)arg;printf("Information received by child thread:\n");printf("name:%s\n",p->name);printf("age:%d\n",p->age);printf("address:%s\n",p->address);returnp;// Return the struct address}intmain(intargc,char*argv[]){PER p={0};printf("Input name: ");fgets(p.name,sizeof(p.name),stdin);p.name[strlen(p.name)-1]='\0';// Remove the newline charactercharbuf[20]={0};printf("Input age: ");fgets(buf,sizeof(buf),stdin);p.age=atoi(buf);// Convert string to integer and assign to p.ageprintf("Input address: ");fgets(p.address,sizeof(p.address),stdin);p.address[strlen(p.address)-1]='\0';// Remove the newline characterpthread_ttid;// Pass the struct address to the child threadpthread_create(&tid,NULL,th,&p);void*ret=NULL;pthread_join(tid,&ret);printf("Returned struct address: %p\n",ret);// Verify the returned dataprintf("Verified age: %d\n",((PER*)ret)->age);return0;}
Key Notes:
  1. To pass multiple parameters to a thread, encapsulate them in a struct and pass the struct address (avoids type conversion issues with multiple parameters).
  2. The struct is allocated in the main thread’s stack; ensure the main thread does not exit before the child thread finishes using the struct (otherwise, the stack is released, leading to wild pointers).
  3. Running result: The child thread prints the user information passed by the main thread, and the main thread verifies the returned struct data.

Example 08: Thread Resource Sharing (08.c)

Function: Demonstrate resource sharing between threads (modify global variables)
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<unistd.h>#include<pthread.h>inta=20;// Global variable (shared by all threads)void*thread(void*arg){a+=10;// Child thread modifies the global variableprintf("Child thread: a = %d\n",a);returnNULL;}intmain(){pthread_ttid;pthread_create(&tid,NULL,thread,NULL);// Wait for the child thread to complete to ensure the modification takes effectpthread_join(tid,NULL);printf("Main thread: a = %d\n",a);// Main thread reads the modified global variablereturn0;}
Key Notes:
  1. Threads share global variables and static variables; modifications to global variables by child threads are visible to the main thread.
  2. If multiple threads modify shared resources simultaneously, synchronization mechanisms (e.g., mutexespthread_mutex_t) are required to avoid race conditions.
  3. Running result: The child thread outputsa = 30, and the main thread also outputsa = 30, confirming resource sharing.

III. Summary of Key Points

  1. Thread Creation: Usepthread_createto create threads, specifying the callback function and parameters; remember to link thepthreadlibrary during compilation (-lpthread).
  2. Thread ID: Usepthread_self()to get the current thread ID, formatted with%lu.
  3. Thread Exit: Child threads can exit actively withpthread_exit()(returning status) or be canceled by the main thread withpthread_cancel().
  4. Resource Recycling: Usepthread_join()for blocking recycling (to get the return value) orpthread_detach()for automatic recycling (to avoid memory leaks).
  5. Resource Sharing: Threads share global variables and static variables, but independent stack areas require dynamic memory allocation for cross-thread data transfer.
  6. Common Pitfalls:
    • Forgetting to link thepthreadlibrary during compilation (leading to undefined reference errors).
    • Returning stack variables from child threads (stack release causes wild pointers).
    • Not recycling thread resources (leading to zombie threads and memory leaks).
    • Race conditions when multiple threads modify shared resources (needing synchronization mechanisms).

By mastering the theoretical knowledge and practical skills in this article, you can efficiently implement concurrent programming in Linux using POSIX threads. For complex scenarios (e.g., thread synchronization, deadlock prevention), further study of mutexes, condition variables, and other advanced technologies is recommended.

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/10 12:22:46

打破设备壁垒,让实验室智能 “协同作战”

当自动化成为实验室标配&#xff0c;许多用户却陷入新的困境&#xff1a;昂贵的智能设备各自为战&#xff0c;数据孤岛难以打通&#xff0c;流程编排耗时耗力&#xff0c;一个环节出错便可能导致整个实验停滞。如何让自动化真正落地&#xff0c;而非停留在 “硬件堆砌”&#x…

作者头像 李华
网站建设 2026/5/10 0:17:20

特长生 VS 全科生:AI与AGI的本质区别,一张文说清

近期看到新闻——酷特智能跑通了首个行业级的AGI&#xff08;通用AI&#xff09;&#xff0c;想来聊聊AI与AGI。简单来说&#xff0c;AI&#xff08;人工智能&#xff09;是我们今天正在广泛使用的技术&#xff0c;而AGI&#xff08;通用人工智能&#xff09;是我们努力迈向的未…

作者头像 李华
网站建设 2026/5/9 19:50:36

Dify对接Spring AI总失败?一文看懂版本依赖的4大雷区

第一章&#xff1a;Dify 与 Spring AI 的版本兼容在构建基于 Java 的 AI 应用时&#xff0c;Spring AI 框架为开发者提供了简洁的抽象层&#xff0c;而 Dify 作为低代码 AI 编排平台&#xff0c;支持快速集成外部服务。确保 Dify 与 Spring AI 的版本兼容性是实现稳定通信的关键…

作者头像 李华
网站建设 2026/5/9 5:22:23

对比多线程与batch(在极简单cnn上操作)

batch&#xff0c;从学习dos时&#xff0c;就认识了这个单词&#xff0c;它叫做批处理&#xff01;现在我发现他与并行或多线程是有差别的&#xff01;我们前头所有程序凡是用到batch&#xff0c;均是如下操作&#xff0c;比如batch3&#xff1a;输入一张图片&#xff0c;forwa…

作者头像 李华
网站建设 2026/5/5 18:55:13

乐迪信息:智慧煤矿解决方案:AI摄像机智能预警系统

AI摄像机智能预警系统为煤矿安全生产提供了全新的技术路径。该系统通过在煤矿关键区域部署智能摄像设备&#xff0c;结合AI算法实现对人员行为、设备状态及环境风险的实时识别与预警&#xff0c;有效提升了煤矿安全管理水平。一&#xff1a;系统架构与技术原理AI摄像机智能预警…

作者头像 李华
网站建设 2026/5/1 0:11:45

新教程!AI大模型部署核心:FastAPI从入门到实战!

AI风口正当时&#xff0c; 想从Python基础迈向高薪开发&#xff1f; 想在AI浪潮中手握核心部署能力&#xff1f; 黑马程序员《Python Web开发&#xff1a;FastAPI从入门到实战》全新教程&#xff0c;正式上线&#xff01;一套教程让你轻松掌握AI大模型部署核心技能&#xff…

作者头像 李华