Linux系统编程(五)多线程
目录
- 一、基本知识点
- 二、线程的编译
- 三、 线程相关函数
- 1. 线程的创建
- 2. 线程的退出
- 3. 线程的等待
- 补充
- 四、综合举例
一、基本知识点
线程(Thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一个标准的线程由线程ID、当前指令指针(PC)、寄存器集合和堆栈组成。它与同属一个进程的其他的线程共享进程的资源,如内存空间、文件描述符和其他一些进程相关的属性。
相比于进程而言,线程更加轻量级,因为它们共享了进程的地址空间以及其他资源,所以线程之间的切换和通信会更加高效。一个进程可以包含多个线程,这些线程可以并发执行,各自独立完成一些特定的任务,或者共同完成一个复杂的任务。主线程结束,则所有线程结束。
在多线程编程中,通常会涉及到线程的创建、同步、互斥、通信等操作,以确保线程之间的协调运行,避免资源竞争和数据不一致的问题。
二、线程的编译
Linux 的线程是通过用户级的函数库实现的,一般采用 pthread
线程库实现线程的访问和控制。它用第 3 方 posix 标准的 pthread,具有良好的可移植性。在使用了线程的代码编译的时候要在后面加上 -lpthread
。
例如:gcc test.c -o test -lpthread
三、 线程相关函数
头文件:#include <pthread.h>
1. 线程的创建
int pthread_create(pthread_t* thread, pthread_attr_t * attr, void *(*start_routine)(void *), void * arg);
//pthread_t* thread :线程的句柄,用于区分是哪个线程。
//pthread_attr_t * attr :线程的属性,通常为NULL。
//void *(*start_routine)(void *) :线程所执行的函数,该函数形参和返回值都要为void *。
// void * arg :该值用于传递第三个参数函数的形参,如果不传递可以为NULL。
2. 线程的退出
函数 pthread_exit 表示线程的退出。其传入的的参数可以被其它线程用 pthread_join
等待函数进行捕获。例如: pthread_exit( (void*)3 );
表示线程退出,并将 3作为返回值被后面的 pthread_join 函数捕获。该函数的作用就是可以将该线程的计算结果传递给创建它的主线程或者其他线程。
注意:在使用线程函数时,不能随意使用 exit 退出函数进行出错处理,由于 exit 的作用是使调用进程终止,往往一个进程包括了多个线程,所以在线程中通常使用 pthread_exit 函数来代替进程中的退出函数 exit。
void pthread_exit(void *retval);
//void *retval:作为线程退出时的值。如果不需要捕获该值,可以传入NULL。
3. 线程的等待
当父线程结束的时候,如果没有 pthread_join
函数等待子线程执行的话,父线程会退出,而主线程的退出会导致进程的退出,故子线程也会退出。
由于一个进程中的多个线程是共享数据段的,因此通常在线程退出之后,退出线程所占用的资源并不会随着线程的终止而得到释放。正如进程之间可以通过 wait()函数系统调用来同步终止并释放资源一样,线程之间也有类似的机制,那就是 pthread_join 函数。这个函数是一个线程阻塞函数,调用这函数的线程将一直等待直到被等待的线程结束为止,当函数返回时,被等待线程的资源被回收。
int pthread_join(pthread_t pthid, void **thread_return);
//pthread_t pthid :线程句柄。
//void **thread_return : 用于接收线程退出的返回值。如果没有需要接收的填NULL。
补充
一般线程的退出和线程的等待是一起使用的。这里我们使用几种参数类型进行举例。
(1)返回整型
int a=10;
pthread_exit((void *) &a);
(2)返回浮点数
int f=10.12;
pthread_exit((void *) &f);
(3)返回字符串
char *string="i love you!";
pthread_exit(string);
(4)返回结构体
typedef struct
{char name[10];int number;float score;
}student;
//方式一
student *people;
pthread_exit(people);
//方式二
student people;
pthread_exit((void *)&people);
举例:
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>void *func1 (void *arg)
{int n=5; float *p=(float *)arg; while(1){ if(n<=0) break; printf("我是子线程,参数为:%f\n", *p);n--;sleep(1);} pthread_exit( (void*)123 );
} int main(int argc, char **argv)
{int ret;int thread_result; float f_number=0.255; pthread_t thread1; //线程句柄//创建线程:ret=pthread_create(&thread1, NULL, func1, (void *)&f_number); //最后一个参数要取地址!if(ret!=0){perror("pthread_create error!\n");return -1;}//等待子线程退出,并释放其占用的资源pthread_join(thread1, (void **)&thread_result);printf("thread_result:%d\n", thread_result);
}
四、综合举例
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>void *fun1(void * arg) //线程1函数
{float *num =(float *)arg;while(1){sleep(1);printf("这是子线程1,传入的值为%f\n",*num);}
}void *fun2(void * arg) //线程2函数
{int *num =(int *)arg;char *string="pthread2_end"while(1){ sleep(1);printf("这是子线程2,传入的值为%d\n",*num);*num--;if(*num <0) break;}pthread_exit((void *)&string);
}int main()
{float pthread1_arg=11.2; //传入线程函数1的参数int pthread2_arg=3; //传入线程函数2的参数int ret;pthread_t thread1,thread2;//线程句柄//创建线程1ret=pthread_create(&thread1, NULL, fun1, (void *) &pthread1_arg);if(ret<0) {perror("pthread1_create error!\n");return -1;}//创建线程2ret=pthread_create(&thread2, NULL, fun2, (void *) &pthread2_arg);if(ret<0) {perror("pthread2_create error!\n");return -1;}while(1){sleep(1);printf("我是主线程\n");}return 0;
}
相关文章:

Linux系统编程(五)多线程
目录 一、基本知识点二、线程的编译三、 线程相关函数1. 线程的创建2. 线程的退出3. 线程的等待补充 四、综合举例 一、基本知识点 线程(Thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一个标准…...

HTTP Basic Access Authentication Schema
HTTP Basic Access Authentication Schema 背景介绍流程安全缺陷参考 背景 本文内容大多基于网上其他参考文章及资料整理后所得,并非原创,目的是为了需要时方便查看。 介绍 HTTP Basic Access Authentication Schema,HTTP 基本访问认证模式…...
#职场发展#其他
一闪论文是目前市场上一款非常靠谱的论文写作工具,不仅可以帮助用户快速完成论文撰写,还能对文章进行查重降重,确保内容原创性。从用户的角度来看,一闪论文确实是一个非常方便、实用的工具,能够大大提高写作效率&#…...

【Text2SQL 论文】评估 ChatGPT 的 zero-shot Text2SQL 能力
论文:A comprehensive evaluation of ChatGPT’s zero-shot Text-to-SQL capability ⭐⭐⭐⭐ arXiv:2303.13547 这篇论文呢综合评估了 ChatGPT 在 zero-shot Text2SQL 任务上的表现。 dataset 使用了 Spider、Spider-SYN、Spider-DK、Spider-Realistic、Spider-CG…...
安卓手机APP开发___设置闹钟
安卓手机APP开发___设置闹钟 目录 概述 设置不精确闹钟 在特定时间后发出闹钟 在特定时间范围内触发闹钟 以大致有规律的时间间隔响起重复闹钟 设置精确的闹钟 系统会在未来的某个精确时刻调用精确闹钟。 可能不需要精确闹钟的用例 设置精确闹钟的方法 系统资源消耗…...

如何评价GPT-4o
目录 1.概述 2.对比分析 2.1.版本 2.2.区别 2.2.1.技术方面的差异 2.2.2.性能提升 2.2.3.应用领域扩展 2.2.4.对未来发展的影响 3.技术能力 4.个人感受 1.概述 GPT-4o的发布无疑是人工智能领域的一次重要进展。作为GPT-4的升级版本,GPT-4o不仅在处理速度…...
自定义窗口事件循环系统
1.定义事件类型,mouse,wheel,drag,view。已处理的事件,accept需设置为true,防止重叠热区继续穿透。记录事件生成时间,全局位置和当前帧窗口下位置。 2.定义事件响应系统interactionSystem&…...
随机森林算法教程(个人总结)
背景 随机森林(Random Forest)是一种集成学习方法,主要用于分类和回归任务。它通过构建多个决策树并将其结果进行集成,提升模型的准确性和鲁棒性。随机森林在处理高维数据和防止过拟合方面表现出色,是一种强大的机器学…...

解决Android studio 一直提示下载gradle-xxx-all.zip问题
今天用AndroidStdiod打开一个新工程的时候,发现项目一直卡在正在下载gradle-xxx-all.zip的任务上,网络出奇的慢,即使配了VPN也无济于事,于是按照以往经验:将gradle-xxx-all.zip下载到.gradle\gradle\wrapper\dists目录…...

3DEXPERIENCE DELMIA Role: RVN - Robotics Virtual Commissioning Analyst
Discipline: Robotics Role: RVN - Robotics Virtual Commissioning Analyst 通过准确地模拟连接到PLC程序的机器人、设备和传感器,在制造虚拟孪生上执行虚拟调试情景 为任何机器人角色的多周期情景创建传感器,生成和变换零件启用 PLC 程序的虚拟验证和…...

js知识点之闭包
闭包 什么是闭包 闭包,是 JavaScript 中一个非常重要的知识点,也是我们前端面试中较高几率被问到的知识点之一。 打开《JavaScript 高级程序设计》和《 JavaScript 权威指南》,会发现里面针对闭包的解释各执一词,在网络上搜索关…...

LORA微调,让大模型更平易近人
技术背景 最近和大模型一起爆火的,还有大模型的微调方法。 这类方法只用很少的数据,就能让大模型在原本表现没那么好的下游任务中“脱颖而出”,成为这个任务的专家。 而其中最火的大模型微调方法,又要属LoRA。 增加数据量和模…...
LabVIEW全自动样品处理系统有哪些优势?
基于LabVIEW的全自动样品处理系统在现代科研和工业应用中展现出显著的优势,其在数据采集、分析和控制方面的性能使其成为提高效率和精度的理想选择。以下是该系统的详细优势: 高效自动化 LabVIEW的图形化编程语言极大地简化了自动化流程的开发。用户可…...
shell脚本操作http请求的返回值——shell处理json格式数据
日常工作中,我们经常会遇到http请求会返回大量格式固定的数据,而我们只需要其中的一部分,那么怎么提取我们想要的字段呢。 这里会介绍一种用shell脚本处理http请求返回,或者处理json格式数据的方式。 这里我们用到了 jq这个强大的…...
leetcode力扣 300. 最长递增子序列 II
给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。 示例 1&#…...
C++_vector简单源码剖析:vector模拟实现
文章目录 🚀1.迭代器🚀2.构造函数与析构函数⚡️2.1 默认构造函数vector()⚡️2.2 vector(int n, const T& value T())⚡️内置类型也有构造函数 ⚡️2.3 赋值重载operator⚡️2.4 通用迭代器拷贝⚡️2.5 vector(initializer_list<T> il)⚡️…...

第3章 数据链路层
王道学习 考纲内容 (一)数据链路层的功能 (二)组帧 (三)差错控制 检错编码;纠错编码 (四)流量控制与可靠传输机制 流量控制、可靠传输与滑动窗口…...

使用OrangePi KunPeng Pro部署AI模型
目录 一、OrangePi Kunpeng Pro简介二、环境搭建三、模型运行环境搭建(1)下载Ollama用于启动并运行大型语言模型(2)配置ollama系统服务(3)启动ollama服务(4)启动ollama(5)查看ollama运行状态四、模型部署(1)部署1.8b的qwen(2)部署2b的gemma(3)部署3.8的phi3(4)部署4b的qwen(5)部…...

SpringMVC 数据映射VC
从 view 层发送请求到Controller,在Controller中获取参数: 在不输入值时会报400,参数错误 在不输入值时num默认为null 没有找到对应标签名称叫nums的,输入任何值时都报400 设置required默认值为false,即使表单没有nums…...

Clickhouse Bitmap 类型操作总结—— Clickhouse 基础篇(四)
文章目录 创建 Bitmap 对象Bitmap 转换为整数数组计算总数(去重)值指定start, end 索引生成子 Bitmap指定 start 索引和数量限制生成子 Bitmap指定偏移量生成子 Bitmap是否包含指定元素两个 Bitmap 是否存在相同元素一个是否为另一个 Bitmap 的子集求最小…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...

聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...

Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...
PAN/FPN
import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...

数据结构第5章:树和二叉树完全指南(自整理详细图文笔记)
名人说:莫道桑榆晚,为霞尚满天。——刘禹锡(刘梦得,诗豪) 原创笔记:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 上一篇:《数据结构第4章 数组和广义表》…...

leetcode_69.x的平方根
题目如下 : 看到题 ,我们最原始的想法就是暴力解决: for(long long i 0;i<INT_MAX;i){if(i*ix){return i;}else if((i*i>x)&&((i-1)*(i-1)<x)){return i-1;}}我们直接开始遍历,我们是整数的平方根,所以我们分两…...