【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.xdnf.cn/news/10577.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

免费送源码:Java+springboott+MySQL+Tomcat 游戏攻略网站设计与实现 计算机毕业设计原创定制

摘 要 随着国民生活水平的逐渐提高&#xff0c;每逢假期或空闲时节走出家门游山玩水已渐渐成为人们生活的一部分。互联网的普及给人们带来的便利不需多说&#xff0c;因此如果把游戏产业与互联网结合起来&#xff0c;利用Java技术建设游戏攻略网站&#xff0c;实现游戏资讯管理…

从0开始的STM32之旅8 串口通信(II)

目录 在开始理解底层原理之前&#xff0c;我们先尝试一下 怎么做 进一步理解 HAL_UART_Transmit HAL_UART_Receive 在开始理解底层原理之前&#xff0c;我们先尝试一下 现在我们综合一下&#xff0c;要求完成如下的事情&#xff1a; 在主程序中存在一个flag变量描述当前有…

springboot的增删改查商城小实践(b to c)

首先准备一张表&#xff0c;根据业务去设计表 订单编号是参与业务的&#xff0c;他那订单编号里面是有特殊意义的&#xff0c;比如说像什么一些年月日什么的&#xff0c;一些用户的ID都在那编号里面呢&#xff1f;不能拿这种东西当主件啊 根据数据量去决定数据类型 价格需要注意…

AndroidStudio-视图基础

一、设置视图的宽高 1.在XML文件中设置视图宽高 视图宽度通过属性android:layout_width表达&#xff0c;视图高度通过属性android:layout_height表达&#xff0c;宽高的取值主要有下列三种: &#xff08;1&#xff09;wrap_content:表示与内容自适应。对于文本视图来说&…

电子科大、同济大学与新加坡国立大学联合发布Math-LLaVA:增强多模态大语言模型的数学推理能力

一、结论写在前面 下面介绍的论文来自&#xff1a;电子科技大学、新加坡科技设计大学、同济大学、新加坡国立大学。 论文标题&#xff1a;Math-LLaVA: Bootstrapping Mathematical Reasoning for Multimodal Large Language Models 论文链接&#xff1a;https://arxiv.org/p…

高校体育场管理系统+ssm

摘 要 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;高校体育场管理系统被用户普遍使用&#xff0c;为方便用户…

杂谈:业务说的场景金融是什么?

引言&#xff1a;市场格局的转变 在供应短缺的年代&#xff0c;是典型的卖方市场。为了保证稳定供货&#xff0c;买方会提前一段时间下单&#xff0c;也几乎没什么议价能力。卖方只需等着接单就行。 现在很多领域的供应商数量越来越多&#xff0c;而且随着互联网的普及&#…

知从科技受邀出席ARM日产技术日

10月29日&#xff0c;上海知从科技有限公司受 ARM 之邀&#xff0c;参与了由其主办的日产技术日活动。此次活动在日本神奈川县厚木市的日产技术中心盛大举行&#xff0c;这一活动汇聚了行业内的前沿技术与精英人才&#xff0c;成为科技创新技术交流的重要平台。 知从科技积极参…

驱动前的准备

驱动前的准备 目录 驱动前的准备 移植SDK 补充&#xff1a;怎么使用我的虚拟机/怎么把自己的虚拟机拷贝到其他磁盘 移植SDK -- 将压缩包复制到虚拟机里面 -- 删除备份文件 -- 解压这个压缩包(会占用大量的空间->有空间再去做&#xff01;) 补充&#xff1a;怎么使用我的…

【网页设计】CSS 定位

目标 能够说出为什么要用定位能够说出定位的4种分类能够说出4种定位各自的特点能够说出为什么常用子绝父相布局能够写出淘宝轮播图布局能够说出显示隐藏的2种方式以及区别 1. 定位 1.1 为什么需要定位 提问&#xff1a; 以下情况使用标准流或者浮动能实现吗&#xff1f;1. …

Spring Boot框架:计算机课程管理的工程认证之桥

3系统分析 3.1可行性分析 通过对本基于工程教育认证的计算机课程管理平台实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本基于工程教育认证的计算机课程管理平…

yolov10断点续训

1. 前言 我们在使用yolov10进行训练的时候往往会因为各种各样的原因中断训练&#xff0c;如&#xff1a; 开了太多程序导致崩溃突然断电其他原因 这时候如果下次能继续上次训练的结果继续训练会节省很多时间 2.复现与解决办法 2.1 正常启动训练 我们先正常启动一个训练 …

【笔记】LLC电路工作频点选择 2-1 输出稳定性的限制

LLC工作模式的分析参考了&#xff1a;现代电力电子学&#xff0c;电力出版社&#xff0c;李永东 1.LLC电路可以选择VCS也可以选择ZVS 1.1选择ZCS时&#xff0c;开关管与谐振电感串联后&#xff0c;与谐振电容并联&#xff1a; 1.2选择ZVS时&#xff0c;开关管仅仅安装在谐振电…

手把手教你写Unity3D飞机大战(4)人机飞机的移动

写在最前面的话 上一篇博客&#xff0c;我们控制了玩家的移动&#xff0c;但这还不够&#xff0c;我们需要让敌方也动起来。 一、大致概要 人机的移动&#xff0c;我们采用随机数来控制&#xff0c;分别包括&#xff08;前进&#xff0c;转弯&#xff0c;爬升&#xff0c;俯冲&…

Spring Boot助力计算机课程管理:符合工程认证

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了基于工程教育认证的计算机课程管理平台的开发全过程。通过分析基于工程教育认证的计算机课程管理平台管理的不足&#xff0c;创建了一个计算机管理基于工程教育认…

Vue2基础

1.环境准备 安装脚手架&#xff1a;全局安装 作用&#xff1a;在任何一个目录下都能通过vue命令创建项目 注意&#xff1a;低版本的node执行这行命令可能会报错&#xff0c;需要升级版本 npm install -g vue/cli 创建项目 在指定的目录下&#xff0c;执行命令 作用&…

RAG如何提升视觉问答?剑桥大学博士论文《使用检索方法增强多模态问答系统》

开发能够处理复杂任务的人工智能系统的需求推动了深度学习的快速发展&#xff0c;尤其是自 2016 年以来&#xff0c;神经网络模型已成为主流方法。这些模型的应用范围广泛&#xff0c;从推荐系统到语音识别&#xff0c;彻底变革了多个领域。然而&#xff0c;仍然存在一些挑战&a…

C++初阶学习第九弹-----vector的模拟实现

C初阶学习第六弹------标准库中的string类_c# string[]-CSDN博客 C初阶学习第七弹——string的模拟实现-CSDN博客 C初阶学习第八弹--深入解析vector的使用-CSDN博客 一.vector的成员变量 目录 一.vector的成员变量 二.vector的模拟实现 2.1vector的构造与析构 2.2迭代器…

提升网站流量的搜索引擎优化实用指南

内容概要 搜索引擎优化&#xff08;SEO&#xff09;是提升网站可见性与流量的重要过程。在当今数字时代&#xff0c;理解这一领域的基本概念至关重要。SEO不仅仅是关于提高关键词排名&#xff0c;更是关于如何创造更好的用户体验和吸引目标受众。以下是一些关键要素&#xff0…

求教0基础入门大模型的学习路线?java出身,数学良好,希望入局大模型算法,有无必要从cnn学起?

目录 前言&#xff1a; Prompt工程&#xff1a; 2.AI编程 3.API调用 4.大模型应用开发 1)RAG 2)Agent 5.深水区&#xff1a;模型训练和微调 1)Fine-tuning 2)多模态 6.产品和交付 前言 本人本科学历java开发出身&#xff0c;数学基础良好&#xff0c;希望入局大模…