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

什么是单线程

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

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倍的效果。
这是多线程相较于单线程所带来的任务执行效率的提升,而多线程和单线程绝不仅仅这一点区别,更多内容将在后续逐步揭开,下一节将介绍线程的基本用法,如何创建、回收、设置线程执行函数等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

csdnGuoYuying

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值