【Linux多线程编程】1. 多线程与单线程

news2024/11/20 7:05:36

什么是单线程

在描述什么是多线程之前,先讲讲什么是单线程。

int var = 100; // 全局变量 var,初始值为 100
void func(){
    var += 100;
    std::cout << "now var is: " << var << std::endl; // c++ 语法,意思为输出 var 的当前值
}
int main()
{
	func();
	func();
}

上面这段代码中,定义了一个函数func,并在main中连续调用两次func,程序执行结果如下:

now var is: 200
now var is: 300

var是一个全局变量,每次调用func,行为都是将var的值+100,整个程序是顺序执行的,第一次调用func,输出now var is: 200,第二次调用func输出now var is: 300
这是一个典型的单线程程序,所有代码自main函数的第一行开始,依次执行每条语句,到最后一行结束

多线程示例

再来看一段多线程的代码

#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <cstring>

int var = 100;

void* func(void * arg){
    int i = *((int*)arg);
    sleep(i); // 等待 i 秒
    var += 100;
    std::cout << i << "th pthread is created!" << " pid = " << getpid() << std::endl; // 输出线程id
    std::cout << "now var is: " << var << std::endl; // 输出 var 值
    return  NULL;
}

int main(){
    std::cout << "at first var = " << var << std::endl; // 输出 var 的起始值
    const int& num = 5;
    int i;
    int index[num];
    pthread_t tid;
    for(i = 0; i < num; ++i){ // 循环创建多个线程
        index[i] = i;
        int ret = pthread_create(&tid, NULL, func, (void*)&(index[i])); // 创建一个线程,每个线程执行函数 func后退出
        if(ret < 0){
            std::cerr << "PTHREAD_CREATE " << strerror(ret) << std::endl;
            exit(1); // 创建失败程序异常退出
        }
    }
    sleep(i); // 主线程休眠 num(5) 秒
    std::cout << "at last var = " << var << std::endl; // 输出 var 的最终值
    return 0;
}

这段代码使用pthread_create创建了5个线程,每个线程执行func后退出,最后主线程退出
现在看不懂这段代码没有关系,今天主要是为了讲明白多线程和单线程的区别是什么?这段代码最终的目的就是让var从初始值100增加到最终值600。要达成同等的目的,我们依旧可以使用单线程,在main中连续调用5次func,或者循环5次调用func,也就是,可能写出以下的单线程代码来让var的值从100增加到600

// 连续调用5次
int main()
{
	func();
	func();
	func();
	func();
	func();
}
// 使用循环
int main()
{
	for (int i = 0; i < 5; ++i) {
		func();
	}
}

这样看貌似单线程确实和多线程没有区别,那我们使用多线程的目的是什么?

为什么使用多线程

思考一个问题:怎样更快速的进行文件压缩?
毫无疑问,文件压缩的速度直接决定了用户的使用体验,作为一个文件压缩软件,速度是必不可少的竞争点,假如我们掌握了文件压缩的算法,其函数声明如下:
int zip_file(FILE *pfile, int offset, int length);

pfile: 文件指针
offset: 起始压缩位置
length: 压缩长度
返回值:0/1 压缩成功/失败

单线程去进行文件压缩,可能写出下面的代码

int ziped = 0; // 已经压缩的长度
int offset = 0; // 起始压缩位置,从文件开头开始
int one_zip_len = 1024 * 1024; // 每次压缩 1MB
while (ziped < pfile.size()) { // pfile.size() 文件总长度
	if (zip_file(pfile, offset, one_zip_len) == 1) { // 压缩 pfile [offset, offset+one_zip_len) 之间的数据
		printf("zip file %p failed, exit 1\n", pfile); // 压缩失败,退出
		exit(1);
	}
	offset += one_zip_len; // 1MB 压缩成功,压缩下1MB
	ziped += one_zip_len;
}

压缩过程如下图所示,先压缩0-1M,然后压缩1-2M,…,最后第n次调用zip_file压缩文件最后的部分
在这里插入图片描述
如果 zip_file压缩1MB需要1s,压缩100M的文件就需要100s,一分半钟的时间只压缩了100MB的文件,这样的速度对于用户来说是不可接受的。
如果可以同时进行压缩数据呢?如果上图中的1-n次,可以同时执行,也就是在0-1s内,同时压缩文件的0-1M、3-4M、7-8M、11-12M,1s结束后,就压缩了4MB的数据,100MB的数据只需要25s就可以完成,效率提升了4倍。

而多线程就是创建多个线程并发执行任务,我们创建4个线程,让每个线程都去执行zip_file,同时控制每个线程压缩不同的文件区域,就可以达到压缩效率提升4倍的效果。
这是多线程相较于单线程所带来的任务执行效率的提升,而多线程和单线程绝不仅仅这一点区别,更多内容将在后续逐步揭开,下一节将介绍线程的基本用法,如何创建、回收、设置线程执行函数等。

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

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

相关文章

【强训】day02

努力经营当下&#xff0c;直至未来明朗&#xff01; 文章目录一、选择二、 编程1. 排序子序列2. 倒置字符串答案1. 选择2. 编程普通小孩也要热爱生活&#xff01; 一、选择 阅读如下代码。 请问&#xff0c;对语句行 test.hello(). 描述正确的有&#xff08;&#xff09; pa…

网站备案信息查询,网站备案号在哪里查询

网站备案号一般是在工信部官方查询&#xff0c;也可以使用第三方工具查询。 1、使用工信部域名信息备案管理系统网站查询 打开工信部的域名信息备案管理系统网站https://beian.miit.gov.cn/&#xff0c;点击ICP备案信息查询&#xff0c;添加需要查询的域名&#xff08;网站网址…

Drools基础与实现(操作实例)

简介&#xff1a; Drools 是用 Java 语言编写的开放源码规则引擎&#xff0c;使用 Rete 算法对所编写的规则求值。Drools 允许使用声明方式表达业务逻辑。可以使用非 XML 的本地语言编写规则&#xff0c;从而便于学习和理解。并且&#xff0c;还可以将 Java 代码直接嵌入到规则…

逻辑漏洞渗透与攻防(一)之身份验证漏洞

目录 逻辑漏洞概要 漏洞的根因&#xff1a; 逻辑漏洞的分类&#xff1a; 身份验证漏洞 暴力破解漏洞 1.1 未限制爆破 1.2 爆破-验证码爆破 1.3 暴力破解漏洞-限制IP爆破 1.4 暴力破解漏洞-限制密码错误次数来爆破 1.5 暴力破解漏洞-多字段爆破 1.6 限制登录频率爆破 …

(小程序)会议OA项目-其它页面

目录 一、tabs组件及会议管理布局 1.自定义tabs组件 2.会议管理 二、投票管理参考图 三、个人中心布局 一、tabs组件及会议管理布局 1.自定义tabs组件 文档参考:自定义组件 | 微信开放文档微信开发者平台文档https://developers.weixin.qq.com/miniprogram/dev/framewo…

植物大战僵尸:实现自动收集阳光

植物大战僵尸这款游戏可以说是很多90后的回忆了&#xff0c;基本上只要是90后或多或少的都接触过&#xff0c;而玩游戏与制作辅助是两个概念&#xff0c;今天我将给大家分享一些游戏辅助方面的制作技巧&#xff0c;之所以使用植物大战僵尸这款游戏是因为游戏简单容易分析&#…

Apache Kafka Spring 集成

Apache Kafka Spring 集成 今天来学习Spring如何集成 Apache kafka&#xff0c;在Spring Boot中如何集成kafka客户端 生产、消费消息。首先介绍下各个组件的版本信息&#xff1a; Apache Kafka_2.13-3.3.1Spring Boot 3.0.0Apache-Maven-3.6.0JDK-17.0.5 启动Kafka # 进入k…

ArcGIS基础实验操作100例--实验38删除冗余节点

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 高级编辑篇--实验38 删除冗余节点 目录 一、实验背景 二、实验数据 三、实验步骤 &#xff08;1&…

免费分享在线设计工具,比ps还方便的贺卡设计工具!

元旦贺卡在线制作工具&#xff0c;不用自己设计&#xff0c;只需借助在线工具平台的模板就能轻松搞定的贺卡设计方法&#xff01;跟着小编下面的设计步骤&#xff0c;使用在线工具乔拓云轻松设计活动贺卡&#xff0c;设计过程简单且一键生成分享链接&#xff0c;不用自己设计工…

推荐四款常见的电子教室软件,大家觉得哪款好用

现在越来越多的教学教室都在使用多媒体教学软件&#xff0c;不仅包括学校&#xff0c;还有一些培训机构和教堂。 那么&#xff0c;多媒体教学软件有哪些&#xff1f; 哪款多媒体教学软件好用&#xff1f; 在今天的文章中&#xff0c;小编挑选了4款流行的多媒体教学软件推荐给大…

【全网最细PAT题解】【PAT乙】1009 说反话(cin、getline、cin.getline三种输入格式)

题目链接 1009 说反话 题目描述 给定一句英语&#xff0c;要求你编写程序&#xff0c;将句中所有单词的顺序颠倒输出。输入格式&#xff1a; 测试输入包含一个测试用例&#xff0c;在一行内给出总长度不超过 80 的字符串。字符串由若干单词和若干空格组成&#xff0c;其中单词…

【Spring 入门教程2】

&#x1f308;博客主页&#xff1a;屠一乐的博客 &#x1f4c5; 发文时间&#xff1a;2023.1.2 &#x1f388; 一定存在只有你才能做成的事 &#x1f339; 博主水平有限&#xff0c;如有错误&#xff0c;欢迎指正 欢迎各位&#x1f44d;收藏&#x1f48e;评论✉ Spring_day02 S…

C++ - opencv应用实例之矩形框检测

C++ - opencv应用实例之矩形框检测 现阶段下,目标检测在实际应用场景中的表现颇为重要,工业质检、移动机器人视觉伺服、作业、交通监控、安防领域等均需要通过目标检测来实现对目标的定位、测量或者统计、辅助控制等目前目标检测主要分为两个方向的发展,其一是基于传统图像处…

let、const、var关键字

1、let ES6中新增的用于声明变量的关键字。 &#xff08;1&#xff09;let声明的变量只在所处于的块级有效 if (true) { let a 10;} console.log(a) // a is not defined 注意&#xff1a;使用let关键字声明的变量才具有块级作用域&#xff0c;使用var声明的变量不具备块级…

计算机网络(二)Linux网络编程

layout: post title: 计算机网络&#xff08;二&#xff09;Linux网络编程 description: 计算机网络&#xff08;二&#xff09;Linux网络编程 tag: 计算机网络 文章目录POSIX概念POSIX网络相关APIsocket()bind()网络字节序与主机字节序&#xff08;大小端设备&#xff09;list…

TensorFlow之过拟合与欠拟合-2

1 基本概念 过度拟合&#xff08;overfit&#xff09; 正则化&#xff08;regularization&#xff09; L1正则化&#xff08;L1 regularization&#xff09; L2正则化&#xff08;L2 regularization&#xff09; 删除正则化&#xff08;dropout regularization&#xff09…

植物大战僵尸:实现灵魂收割者

植物大战僵尸这款游戏可以说是很多90后的回忆了&#xff0c;基本上只要是90后或多或少的都接触过&#xff0c;而玩游戏与制作辅助是两个概念&#xff0c;今天我将给大家分享一些游戏辅助方面的制作技巧&#xff0c;之所以使用植物大战僵尸这款游戏是因为游戏简单容易分析&#…

【JavaSE成神之路】聊聊封装这件事

哈喽&#xff0c;我是兔哥呀&#xff0c;今天就让我们继续这个JavaSE成神之路&#xff01; 这一节啊&#xff0c;咱们要学习的内容是Java的封装。 1. 什么是封装 Java的封装是指&#xff0c;在一个类中把一些重要的信息隐藏起来&#xff0c;使得外部不能直接访问。 Java的封…

Java --- JUC之volatile

目录 一、volatile两大特点 二、volatile的内存语义 三、volatile内存屏障 四、volatile四大屏障 五、volatile的特性 六、volatile使用场景 一、volatile两大特点 1、可见性 2、有序性 二、volatile的内存语义 1、当写一个volatile变量时&#xff0c;JMM会把该线程对…

C语言入门系列 - 共用体union,枚举enum,宏定义#define,条件编译,const与指针

C语言入门系列 - 共用体union,枚举enum&#xff0c;宏定义#define,条件编译,const与指针 第一节 C 语言基础以及基本数据类型 第二节 C 语言运算符 第三节 C 语言控制语句 第四节 C 语言自定义函数 第五节 C 语言修饰变量的关键字 第六节 C 语言构造数据类型–数组 第七节 C 语…