news 2025/12/26 23:31:13

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进行投诉反馈,一经查实,立即删除!
网站建设 2025/12/16 19:09:51

Web前端教程 4

CSS盒子模型弹性盒子模型浮动清除浮动定位CSS新属性媒体查询雪碧图字体图标

作者头像 李华
网站建设 2025/12/16 19:07:18

灵活用工费咋算?亲测案例复盘分享

灵活用工费计算逻辑与技术革新&#xff1a;基于天语灵活用工平台的深度解析行业痛点分析当前灵活用工平台领域面临两大核心挑战&#xff1a;算薪效率与合规风险。传统系统在处理复杂用工场景时&#xff0c;常因多维度变量&#xff08;如工时波动、岗位差异、政策变动&#xff0…

作者头像 李华
网站建设 2025/12/16 19:06:54

2025年12月成都四川工作服厂家推荐:专业品牌排行榜单深度对比分析

一、引言 工作服作为企业形象塑造与员工劳动防护的重要载体&#xff0c;其采购决策直接关系到企业运营成本控制、品牌视觉统一性及员工安全保障。对于成都及周边地区的企事业单位采购负责人、行政管理者以及创业者而言&#xff0c;如何在众多供应商中筛选出具备稳定生产能力、…

作者头像 李华
网站建设 2025/12/16 19:06:18

7个常见错误避免,确保YashanDB实施的成功率

在当前数据驱动的业务环境中&#xff0c;数据库系统作为核心信息基础设施&#xff0c;其性能瓶颈、数据一致性保障及高可用性实现等挑战日益突显。YashanDB作为一款支持多种部署形态的先进数据库系统&#xff0c;集成了行列混合存储、分布式和共享集群架构等多项技术优势&#…

作者头像 李华
网站建设 2025/12/16 19:04:37

从Git仓库获取TensorRT示例代码并运行BERT推理

从Git仓库获取TensorRT示例代码并运行BERT推理 在当前AI应用快速落地的背景下&#xff0c;将大型语言模型高效部署到生产环境已成为工程团队的核心挑战之一。以BERT为代表的Transformer架构虽然在自然语言理解任务中表现出色&#xff0c;但其庞大的参数量和密集的矩阵运算使得…

作者头像 李华
网站建设 2025/12/16 19:03:18

从 paperzz 到 8 款工具:降重 / 降 AIGC 的 “差异化战场”—— 谁能守住学术表达的 “精准与合规”?

学术写作的 “终局考验”&#xff0c;往往藏在初稿完成后的 “细节优化” 里&#xff1a;重复率超标、AIGC 痕迹被检测、表述既冗余又生硬…… 而一批定位 “学术表达优化” 的工具正在涌现 —— 从 paperzz 的 “轻量型精准优化” 到其他工具的 “文献联动降重”“学科化 AIGC…

作者头像 李华