news 2026/4/23 16:01:48

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/23 8:16:37

GitHub Actions持续集成TensorFlow项目时使用清华源提速

GitHub Actions持续集成TensorFlow项目时使用清华源提速 在构建一个基于 TensorFlow 的开源项目 CI 流水线时&#xff0c;你是否曾经历过这样的场景&#xff1a;每次 pip install tensorflow 都像在“看运气”&#xff1f;国际网络波动、下载中断、超时失败……尤其在中国境内…

作者头像 李华
网站建设 2026/4/23 12:53:51

Dify结果过滤难?掌握这3种重排序策略,精准锁定关键信息

第一章&#xff1a;检索重排序的 Dify 结果过滤在构建基于大语言模型的应用时&#xff0c;检索增强生成&#xff08;RAG&#xff09;系统常面临检索结果相关性不足的问题。Dify 作为低代码 AI 应用开发平台&#xff0c;提供了灵活的结果过滤与重排序机制&#xff0c;可有效提升…

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

春节前科技盛宴!小米全家桶扎堆来袭,17 Ultra + 双 Turbo 机皇齐亮相

对数码爱好者来说&#xff0c;年底最期待的莫过于厂商的 “压轴新品秀”。小米这次直接放大招&#xff0c;12 月 14 日曝光的春节前新品清单堪称 “全家桶豪华套餐”—— 从第五代骁龙 8 至尊版加持的小米 17 Ultra&#xff0c;到全球首发天玑 8500 的 REDMI Turbo 5 系列&…

作者头像 李华
网站建设 2026/4/23 9:53:35

构建可持续的自动化测试维护体系

随着敏捷开发与持续集成的普及&#xff0c;自动化测试已成为现代软件工程中不可或缺的一环。然而&#xff0c;许多团队在初期投入自动化后&#xff0c;逐渐面临脚本失效、环境依赖复杂、维护成本高昂等挑战。究其根源&#xff0c;往往是由于缺乏前瞻性的维护策略所致。一、脚本…

作者头像 李华
网站建设 2026/4/23 9:53:08

孩子学编程到底有没有用?这篇文章告诉你!

最近好多家长都在问&#xff1a;现在满大街都在说少儿编程&#xff0c;是不是真的值得学习&#xff1f;我家孩子天天这就知道玩游戏&#xff0c;学这个真的有用吗&#xff1f;说实话&#xff0c;我们能理解大家的焦虑。咱们小时候学的是奥数、英语&#xff0c;现在的孩子起跑线…

作者头像 李华