news 2026/4/16 18:02:12

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/4/16 11:01:12

AI产品核心差异的五大维度

AI产品核心差异的五大维度 抛开具体产品&#xff0c;从技术底层到应用层&#xff0c;主流AI的差异可归纳为以下核心维度&#xff0c;这些维度直接决定产品的适用边界&#xff1a;1. 技术定位&#xff1a;开源与闭源的路线分野这是最根本的差异&#xff0c;直接影响开发者使用权…

作者头像 李华
网站建设 2026/4/15 13:09:01

企业差旅成本优化指南:三大平台助您实现高效出行管理

在当今竞争激烈的商业环境中&#xff0c;企业差旅成本控制已成为财务管理的重要环节。据2024年企业出行调研报告显示&#xff0c;差旅费用通常占据企业运营成本的15%-25%&#xff0c;如何选择合适的差旅平台实现成本优化&#xff0c;已成为众多企业管理者的核心关切。本文将深入…

作者头像 李华
网站建设 2026/4/15 20:23:46

Dify+PDF加密权限控制(仅限高级用户掌握的5个关键技术点)

第一章&#xff1a;加密 PDF 的 Dify 权限验证 在现代文档安全体系中&#xff0c;对敏感 PDF 文件进行加密并结合权限控制系统已成为企业级应用的标准实践。Dify 作为一款支持可扩展插件架构的低代码平台&#xff0c;能够通过自定义节点实现对加密 PDF 文件的访问控制与权限验证…

作者头像 李华
网站建设 2026/4/16 12:46:54

Python中的数据序列其一

目录 前言 一、字符串 1.字符串的定义 2.字符串的切片 3.字符串的操作方法 查找方法 修改方法 判断方法 补充 二、列表 1.列表的定义 2.列表的相关操作 查操作 增操作 删操作 改操作 三、元组 1.元组的定义 2.元组的应用场景 查询方法 总结 前言 在Python编程的舞台上&#xff…

作者头像 李华
网站建设 2026/4/16 13:21:06

(Dify权限校验避坑指南):那些官方文档不会告诉你的细节

第一章&#xff1a;Dify权限校验的核心机制解析Dify 作为一款面向 AI 应用开发的低代码平台&#xff0c;其安全性依赖于严谨的权限校验机制。该机制贯穿用户身份认证、资源访问控制与操作权限判定三个层面&#xff0c;确保系统在开放性与安全之间取得平衡。身份认证流程 Dify 采…

作者头像 李华