深入浅出:C语言线程以及线程锁

目录

线程和线程锁概念

线程锁的概念

线程的特点

线程的使用

创建线程 pthread_create

回收线程pthread_join

退出线程 pthread_exit

线程锁的使用

线程同步之互斥锁(Mutex)

初始化互斥锁

获取互斥锁

释放互斥锁

销毁互斥锁

初始化条件变量

等待条件变量

发送信号

广播信号

销毁条件变量

实例:每次打印都实现翻转数组


线程和线程锁概念

线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。一个进程可以包含一个或多个线程,而每个线程都有自己的指令指针和寄存器状态,它们共享进程的资源,如内存空间、文件句柄和网络连接等。

线程锁的概念

线程锁的基本思想是,只有一个线程能持有锁,其他试图获取锁的线程将被阻塞,直到锁被释放。这样,锁就确保了在任何时刻,只有一个线程能够访问临界区(即需要保护的代码段或数据),从而保证了数据的完整性和一致性。

线程的特点

  1. 轻量级进程:相比进程,线程的创建和切换成本更低,因为它们共享相同的地址空间和资源,不需要进行系统调用和上下文切换。

  2. 并发执行:线程允许在一个进程内部并发执行多个控制流,使得程序能够同时处理多个任务,提高程序的响应速度和效率。

  3. 资源共享:线程共享进程的资源,如内存、文件句柄和网络连接等,这减少了资源的开销,但也要求对共享资源进行同步和保护,以防止数据竞争和不一致。

  4. 通信便捷:由于线程共享同一进程的资源,它们之间的通信比进程间通信更为简单和快速,通常只需要使用局部变量或全局变量即可。

  5. 独立调度和执行:线程可以独立于其他线程进行调度和执行,操作系统可以根据需要将CPU时间分配给不同的线程,而无需切换到不同的进程。

  6. 线程状态:线程也有自己的生命周期,包括创建、就绪、运行、阻塞和终止等状态。线程状态的变化由操作系统调度器控制。

  7. 线程同步:为了保证数据的一致性和完整性,线程在访问共享资源时需要进行同步。常用的同步机制包括互斥锁(mutex)、信号量(semaphore)、条件变量(condition variable)等。

  8. 线程间通信:虽然线程共享资源,但在某些情况下,线程之间也需要进行通信,如通知某一线程完成特定任务或传递数据。这可以通过共享内存、信号量或条件变量等方式实现。

  9. 线程优先级:线程可以有不同的优先级,高优先级的线程在调度时会得到更多的CPU时间,从而影响线程的执行顺序和进程的整体性能。

线程的使用

创建线程 pthread_create

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, 
                    void *(*start_routine) (void *), void *arg);
功能:创建线程
参数:thread:线程标识
            attr:线程属性, NULL:代表设置默认属性
            start_routine:函数名:代表线程函数
            arg:用来给前面函数传参
返回值:成功:0
              失败:错误码

回收线程pthread_join

int  pthread_join(pthread_t thread,  void **value_ptr) 
功能:用于等待一个指定的线程结束,阻塞函数
参数:thread:创建的线程对象
        value_ptr:指针*value_ptr指向线程返回的参数
返回值:成功 : 0
       失败:errno

退出线程 pthread_exit

int  pthread_exit(void *value_ptr) 
功能:用于退出线程的执行
参数:value_ptr:线程退出时返回的值(任意类型)
返回值:成功 : 0
        失败:errno

简单用线程实现一下主线程循环从终端输入,线程函数将数据循环输出,当输入quit结束程序。

线程锁的使用

线程同步之互斥锁(Mutex)

互斥锁(Mutex)是一种用于同步线程访问共享资源的机制,确保在任何时刻只有一个线程能够访问临界区,从而避免了数据竞争和不一致性问题。以下是互斥锁相关函数的详细解析:

初始化互斥锁

C

1int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
  • 功能:初始化互斥锁。
  • 参数
    • mutex:指向要初始化的互斥锁的指针。
    • attr:指向互斥锁属性结构的指针,如果为NULL,则使用默认属性。
  • 返回值:成功返回0,失败返回非零值。
获取互斥锁

C

1int pthread_mutex_lock(pthread_mutex_t *mutex);
  • 功能:尝试获取互斥锁,如果锁已经被另一个线程持有,当前线程将被阻塞,直到锁可用。
  • 参数
    • mutex:指向要获取的互斥锁的指针。
  • 返回值:成功返回0,失败返回非零值。

pthread_mutex_lockpthread_mutex_trylock的区别在于,pthread_mutex_lock是阻塞的,即如果锁被占用,调用线程会等待直至获取到锁;而pthread_mutex_trylock是非阻塞的,如果锁被占用,它会立即返回,不等待锁释放。

释放互斥锁

C

1int pthread_mutex_unlock(pthread_mutex_t *mutex);
  • 功能:释放由当前线程持有的互斥锁。
  • 参数
    • mutex:指向要释放的互斥锁的指针。
  • 返回值:成功返回0,失败返回非零值。
销毁互斥锁

C

1int pthread_mutex_destroy(pthread_mutex_t *mutex);
  • 功能:销毁互斥锁,通常在不再需要互斥锁时调用。
  • 参数
    • mutex:指向要销毁的互斥锁的指针。
  • 返回值:成功返回0,失败返回非零值。
初始化条件变量

C

1int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
  • 功能:初始化条件变量。
  • 参数
    • cond:指向要初始化的条件变量的指针。
    • attr:指向条件变量属性的指针,通常设为NULL以使用默认属性。
  • 返回值:成功返回0,失败返回非零值。
等待条件变量

C

1int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
  • 功能:线程挂起等待,直到条件变量被信号唤醒。
  • 参数
    • cond:指向要等待的条件变量的指针。
    • mutex:与条件变量关联的互斥锁,必须在调用前锁定并在返回后再次锁定。
  • 返回值:成功返回0,失败返回非零值。
  • 注释:当没有条件产生时函数会阻塞,同时会自动解锁互斥锁;一旦条件产生或接收到信号,函数结束阻塞并重新锁定互斥锁。
发送信号

C

1int pthread_cond_signal(pthread_cond_t *cond);
  • 功能:向条件变量发送信号,唤醒一个等待该条件变量的线程。
  • 参数
    • cond:指向条件变量的指针。
  • 返回值:成功返回0,失败返回非零值。
  • 注释:通常在条件满足后调用,以通知等待线程继续执行。
广播信号

C

1int pthread_cond_broadcast(pthread_cond_t *cond);
  • 功能:向条件变量广播信号,唤醒所有等待该条件变量的线程。
  • 参数
    • cond:指向条件变量的指针。
  • 返回值:成功返回0,失败返回非零值。
  • 注释:与pthread_cond_signal类似,但唤醒所有等待线程,而非仅唤醒一个。
销毁条件变量

C

1int pthread_cond_destroy(pthread_cond_t *cond);
  • 功能:销毁条件变量。
  • 参数
    • cond:指向要销毁的条件变量的指针。
  • 返回值:成功返回0,失败返回非零值。

实例:每次打印都实现翻转数组

.

注:由于线程是随机执行的,所以此时我们不得不用上互斥锁,否则就会出现一些意外情况,这与我们使用标志位是一个道理,例如flag为true的时候p1执行,为flase的p2执行,但是线程锁的逻辑更加严谨和细致一些,功能也更多一些。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/767880.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SSMOA办公系统-计算机毕业设计源码19159

摘 要 随着现代信息技术的快速发展以及企业规模不断扩大,实现办公线上流程自动化已成为提升企业核心竞争力的关键。本文主要介绍的是利用Spring、SpringMVC和MyBatis(简称为:SSM)框架,MySQL数据库等先进的互联网开源技…

X86 +PC104+支持WinCE5.0,WinCE6.0,DOS,WinXP, QNX等操作系统,工业控制数据采集核心模块板卡定制

CPU 模块 是一款基于RDC 3306的SOM Express模块。RDC 3306这款X86架构的CPU是一款性能高、稳定性强的处理器。 它是一款灵活精巧的主板(尺寸为91.8mm68.6mm),可以灵活的运用于用户的底板,节约开发成本。模块的接插件使用插针形式…

基于PHP花涧订购系统的设计与实现-计算机毕业设计源码00332

摘 要 近年来,电子商务的快速发展引起了行业和学术界的高度关注。花涧订购系统旨在为用户提供一个简单、高效、便捷的花卉购物体验,它不仅要求用户清晰地查看所需信息,而且还要求界面设计精美,使得功能与页面完美融合,…

固定网国内数据传送业务经营许可证

一、国内固定网数据传送业务是什么? 固定网国内数据传送业务是指互联网数据传送业务以外的,在固定网中以有线方式提供的国内端到端数据传送业务。主要包括基于IP承载网、ATM网、X.25分组交换网、DDN网、帧中继网络的数据传送业务等。该业务属于A2类基础…

Vision Transformer论文阅读笔记

目录 An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale -- Vision Transformer摘要Introduction—简介RELATED WORK—相关工作METHOD—方法VISION TRANSFORMER (VIT)—视觉Transformer(ViT) 分析与评估PRE-TRAINING DATA REQUIREMENTS—预训练数据…

PDF文档如何统计字数,统计PDF文档字数的方法有哪些?

在平时使用pdf阅读或者是处理文档的时候,常常需要统计文档的字数。pdf在查看文字时其实很简单。 PDF文档是一种常见的电子文档格式,如果需要对PDF文档中的字数进行统计,可以使用以下方法: Adobe Acrobat DC:Adobe Ac…

【服装识别系统】图像识别+Python+人工智能+深度学习+算法模型+TensorFlow

一、介绍 服装识别系统,本系统作为图像识别方面的一个典型应用,使用Python作为主要编程语言,并通过TensorFlow搭建ResNet50卷积神经算法网络模型,通过对18种不同的服装(‘黑色连衣裙’, ‘黑色衬衫’, ‘黑色鞋子’, …

从 ClickHouse 到 Apache Doris:快成物流的数智化货运应用实践

导读:随着快成物流的大宗商品产业链的不断发展,货运轨迹规划和实时数据分析的需求日益迫切,为了保障数据报表更新、用户画像圈选与物流轨迹实时更新等大数据核心系统性能,快成物流引入 Apache Doris 实时数仓升级了大数据算法平台…

乘积最大子数组

代码实现&#xff1a; 方法一&#xff1a;暴力法 方法二&#xff1a;动态规划 int maxProduct(int *nums, int numsSize) {long imax nums[0], imin nums[0], res nums[0];for (int i 1; i < numsSize; i) {if (nums[i] < 0) {int temp imax;imax imin;imin temp;…

Taogogo Taocms v3.0.2 远程代码执行漏洞(CVE-2022-25578)

前言 CVE-2022-25578 是一个存在于 Taogogo Taocms v3.0.2 中的代码注入漏洞。此漏洞允许攻击者通过任意编辑 .htaccess 文件来执行代码注入。 漏洞详情 漏洞描述&#xff1a;攻击者可以利用此漏洞上传一个 .htaccess 文件到网站&#xff0c;并在文件中注入恶意代码&#xf…

oracle11.2.0.4 RAC 保姆级静默安装(一) GI集群软件

一、响应文件准备 我们直接使用软件解压后的response文件夹中的响应文件模板进行修改 选择当前服务器的主机名,产品目录是在已存在的/u01/app目录基础上自动创建的无需提前创建oraInventory 按需选择语言,具体语言配置参考表格 一般rac默认选择安装类型为CRS_CONFIG 对应正…

设计模式-状态模式和策略模式

1.状态模式 1.1定义 当一个对象的内在状态改变时允许根据当前状态作出不同的行为&#xff1b; 1.2 适用场景 (1)一个对象的行为取决于它的状态,并且它必须在运行时根据状态来决定其行为. (2)代码中包含了大量的与状态有关的条件语句,例如:一个操作含有庞大的多分值语句(if…

工厂应用的工业一体机需要满足那些条件?

工业一体机作为工业自动化领域中的重要组成部分&#xff0c;已经广泛应用于制造业、加工业和其他工业领域。随着工业4.0时代的到来&#xff0c;工业一体机的使用变得愈加普遍和复杂。为了确保工业一体机在工厂应用中的稳定运行和高效运作&#xff0c;需要满足一些必要的条件。 …

JELR-630HS漏电继电器 30-500mA 导轨安装 约瑟JOSEF

JELR-HS系列 漏电继电器型号&#xff1a; JELR-15HS漏电继电器&#xff1b;JELR-25HS漏电继电器&#xff1b; JELR-32HS漏电继电器&#xff1b;JELR-63HS漏电继电器&#xff1b; JELR-100HS漏电继电器&#xff1b;JELR-120HS漏电继电器&#xff1b; JELR-160HS漏电继电器&a…

Nuxt3 的生命周期和钩子函数(九)

title: Nuxt3 的生命周期和钩子函数&#xff08;九&#xff09; date: 2024/7/3 updated: 2024/7/3 author: cmdragon excerpt: 摘要&#xff1a;本文介绍了Nuxt3中与Vite相关的五个生命周期钩子&#xff0c;包括vite:extend、vite:extendConfig、vite:configResolved、vite…

技术成神之路:设计模式(三)原型模式

1. 定义 原型模式&#xff08;Prototype Pattern&#xff09;是一种创建型设计模式&#xff0c;旨在通过复制现有对象来创建新对象&#xff0c;而不是通过实例化类的方式。这个模式可以提高对象创建的效率&#xff0c;尤其是在创建对象的过程非常复杂或代价高昂时。 2. 结构 原…

创建线程的五种方式

一.继承Thread ,重写run class MyThread extends Thread{Overridepublic void run() {//这里的内容就是该线程要完成的工作while(true) {System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeExceptio…

亚马逊跟卖卖家还在选品发愁吗!已经有卖家用这种方式选品大卖!

对于亚马逊相信很多卖家都不陌生&#xff0c;也有很多新手卖家涌入&#xff0c;但是进入后就不知道怎么选品了&#xff0c;很多新手卖家是不是天天盯着亚马逊页面的产品&#xff0c;眼花撩乱的&#xff0c;不知道那些产品&#xff0c;能跟卖那些不能跟卖&#xff0c;也有些卖家…

Nginx详解-安装配置等

目录 一、引言 1.1 代理问题 1.2 负载均衡问题 1.3 资源优化 1.4 Nginx处理 二、Nginx概述 三、Nginx的安装 3.1 安装Nginx 3.2 Nginx的配置文件 四、Nginx的反向代理【重点】 4.1 正向代理和反向代理介绍 4.2 基于Nginx实现反向代理 4.3 关于Nginx的location路径…

使用python做飞机大战

代码地址: 点击跳转