当前位置: 首页 > news >正文

【Linux】【线程操作与同步】汇总整理

线程(Threads)是现代操作系统中用于并发执行的基本单元。一个进程可以包含一个或多个线程,每个线程都可以独立执行一段程序代码,共享进程的资源(如内存),但拥有自己的栈空间和寄存器状态。下面是对线程的一些基本概念、创建和管理线程的方法以及相关API的汇总整理。

线程概述

线程是进程中的轻量级进程单元,通常在一个进程中创建多个线程来实现并发执行。与进程相比,线程共享相同的地址空间和资源,因此创建和切换线程的成本较低。

创建线程

POSIX 线程库(POSIX Threads, pthreads)
  • 创建线程

    • pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg): 创建一个新的线程。
    • 参数thread用于存储新线程的标识符,attr指定线程属性,start_routine是线程执行的函数入口,arg是传递给该函数的参数。
  • 线程属性

    • pthread_attr_t: 线程属性结构体。
    • pthread_attr_init(pthread_attr_t *attr): 初始化线程属性。
    • pthread_attr_destroy(pthread_attr_t *attr): 销毁线程属性。
    • pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate): 设置线程的分离状态。
    • pthread_attr_setscope(pthread_attr_t *attr, int scope): 设置线程的调度范围。
  • 加入线程

    • pthread_join(pthread_t thread, void **thread_return): 等待一个线程结束,并可获取其返回值。
    • 参数thread指定要等待的线程,thread_return用于存储线程的返回值。
  • 分离线程

    • pthread_detach(pthread_t thread): 使线程分离,即线程结束后不会等待回收资源。

线程控制

  • 获取线程ID

    • pthread_self(void): 获取当前线程的ID。
  • 取消线程

    • pthread_cancel(pthread_t thread): 请求取消一个线程。
    • pthread_setcancelstate(int state, int *oldstate): 设置线程的取消状态。
    • pthread_setcanceltype(int type, int *oldtype): 设置线程的取消类型。
  • 设置线程名称

    • pthread_setname_np(pthread_t thread, const char *name): 设置线程名称。
    • pthread_getname_np(pthread_t thread, char *name, size_t len): 获取线程名称。
  • 线程同步

    • 互斥锁
      • pthread_mutex_t: 互斥锁类型。
      • pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr): 初始化互斥锁。
      • pthread_mutex_lock(pthread_mutex_t *mutex): 锁定互斥锁。
      • pthread_mutex_unlock(pthread_mutex_t *mutex): 解锁互斥锁。
      • pthread_mutex_destroy(pthread_mutex_t *mutex): 销毁互斥锁。
    • 条件变量
      • pthread_cond_t: 条件变量类型。
      • pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *cond_attr): 初始化条件变量。
      • pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex): 等待条件变量。
      • pthread_cond_signal(pthread_cond_t *cond): 唤醒一个等待的线程。
      • pthread_cond_broadcast(pthread_cond_t *cond): 唤醒所有等待的线程。
      • pthread_cond_destroy(pthread_cond_t *cond): 销毁条件变量。
    • 读写锁
      • pthread_rwlock_t: 读写锁类型。
      • pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr): 初始化读写锁。
      • pthread_rwlock_rdlock(pthread_rwlock_t *rwlock): 读锁。
      • pthread_rwlock_wrlock(pthread_rwlock_t *rwlock): 写锁。
      • pthread_rwlock_unlock(pthread_rwlock_t *rwlock): 解锁。
      • pthread_rwlock_destroy(pthread_rwlock_t *rwlock): 销毁读写锁。
  • 线程局部存储

    • pthread_key_t: 线程局部键类型。
    • pthread_key_create(pthread_key_t *key, void (*destructor)(void *)): 创建线程局部键。
    • pthread_setspecific(pthread_key_t key, const void *value): 设置线程局部变量的值。
    • pthread_getspecific(pthread_key_t key): 获取线程局部变量的值。
    • pthread_key_delete(pthread_key_t key): 删除线程局部键。

示例代码

以下是一个简单的示例,展示如何在 Linux 系统上使用 C 语言创建线程,并让线程执行一段简单的代码:

1#include <stdio.h>
2#include <pthread.h>
3#include <stdlib.h>
4
5// 线程执行的函数
6void* thread_function(void *arg) {
7    int thread_id = *((int *)arg);
8    printf("线程 %d 正在运行\n", thread_id);
9    free(arg);  // 释放传入的参数
10    return NULL;
11}
12
13int main() {
14    pthread_t threads[5];
15    int *thread_ids[5];
16
17    for (int i = 0; i < 5; ++i) {
18        thread_ids[i] = (int *)malloc(sizeof(int));
19        *thread_ids[i] = i + 1;
20
21        // 创建线程
22        if (pthread_create(&threads[i], NULL, thread_function, thread_ids[i]) != 0) {
23            perror("无法创建线程");
24            exit(EXIT_FAILURE);
25        }
26    }
27
28    // 等待所有线程结束
29    for (int i = 0; i < 5; ++i) {
30        if (pthread_join(threads[i], NULL) != 0) {
31            perror("无法等待线程");
32            exit(EXIT_FAILURE);
33        }
34    }
35
36    printf("所有线程结束\n");
37
38    return 0;
39}

注意事项

  • 线程之间的数据共享需要通过互斥锁等同步机制来避免竞态条件。
  • 线程局部存储(TLS)可以为每个线程提供独立的存储空间,避免了线程间的干扰。
  • 线程取消需要谨慎处理,以避免资源泄漏或不正确的状态。
  • 在使用条件变量时,总是要在互斥锁的保护下等待和唤醒条件变量。
  • 线程的分离状态决定了线程结束后是否会等待其资源的回收。
  • 在线程中使用动态分配的内存时,需要确保正确释放,避免内存泄漏。

线程是实现并发编程的基础,理解和熟练掌握线程的创建和管理对于编写高性能和可靠的多线程程序至关重要。


http://www.mrgr.cn/news/69626.html

相关文章:

  • golang将word、excel转换为pdf
  • <项目代码>YOLOv8 番茄识别<目标检测>
  • 深度解析 Linux 系统下的 top 命令
  • MYSQL 库,表 基本操作
  • 3216. 交换后字典序最小的字符串
  • 【Android】View—基础知识,滑动,弹性滑动
  • 鸿蒙next版开发:ArkTS组件通用属性(图形变换)
  • AndroidStudio-视图基础
  • 链表的使用
  • 《Agent 工作流 2025》
  • AI与OCR:数字档案馆图像扫描与文字识别技术实现与项目案例
  • 01_docker安装
  • STM32各模块
  • Elasticsearch 实战应用:高效搜索与数据分析
  • 网络编程中非阻塞的实现方式
  • 540. 有序数组中的单一元素
  • SimpleMemory 博客园主题美化
  • 如何自己实现事件的订阅和发布呢?
  • 基于SpringBoot+Vue音乐播放和推荐系统【提供源码+答辩PPT+参考文档+项目部署】
  • PostgreSQL 用户登录失败账号锁定
  • 基于SpringBoot的“生鲜交易系统”的设计与实现(源码+数据库+文档+PPT)
  • numpy np.logical_not函数介绍
  • LLMs在供应链投毒检测中的应用
  • Python中的动态属性管理:使用`__getattr__`和`__setattr__`实现灵活的数据访问
  • 文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《基于数据-模型混合驱动方法的多类型移动应急资源优化调度策略 》
  • 一文带你看懂Java多线程并发,深度剖析AQS源码