文章目录
一、 前言
在windows中进程只是一个容器,用于装载系统资源,它并不执行代码,它是系统资源分配的最小单元,而在进程中执行代码的是线程,线程是轻量级的进程,是代码执行的最小单位。
多线程的用处:
- 任务分解:
- 耗时的操作,任务分解,实时响应
- 数据分解:
- 充分利用多核CPU处理数据
- 数据流分解:
- 读写分流,解耦合设计
1.1 进程和线程
先从概念上了解一下线程和进程之间的区别:
-
进程有自己独立的地址空间, 多个线程共用同一个地址空间
- 线程更加节省系统资源, 效率不仅可以保持的, 而且能够更高
- 在一个地址空间中多个线程独享: 每个线程都有属于自己的栈区, 寄存器(内核中管理的)
- 在一个地址空间中多个线程共享: 代码段, 堆区, 全局数据区, 打开的文件(文件描述符表)都是线程共享的
-
线程是程序的最小执行单位, 进程是操作系统中最小的资源分配单位
- 每个进程对应一个虚拟地址空间,一个进程只能抢一个CPU时间片
- 一个地址空间中可以划分出多个线程, 在有效的资源基础上, 能够抢更多的CPU时间片
- 多线程之间是无序的状态,时间片是随机分配
-
CPU的调度和切换: 线程的上下文切换比进程要快的多
**上下文切换:**进程/线程分时复用CPU时间片,在切换之前会将上一个任务的状态进行保存, 下次切换回这个任务的时候, 加载这个状态继续运行,任务从保存到再次加载这个过程就是一次上下文切换。 -
线程更加廉价, 启动速度更快, 退出也快, 对系统资源的冲击小。
二、 创建线程
一个程序至少有一个线程,这个线程称为主线程(main thread),如果我们不显示地创建线程,那我们产的程序就是只有主线程的间线程程序。
2.1 线程函数pthread_self(void)
每一个线程都有一个唯一的线程ID,ID类型为pthread_t,这个ID是一个无符号长整形数,如果想要得到当前线程的线程ID,可以调用如下函数:
pthread_t pthread_self(void); // 返回当前线程的线程ID
在一个进程中调用线程创建函数,就可得到一个子线程,和进程不同,需要给每一个创建出的线程指定一个处理函数,否则这个线程无法工作。
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
// Compile and link with -pthread, 线程库的名字叫pthread, 全名: libpthread.so libptread.a
参数:
- thread: 传出参数,是无符号长整形数,线程创建成功, 会将线程ID写入到这个指针指向的内存中
- attr: 线程的属性, 一般情况下使用默认属性即可, 写NULL
- start_routine: 函数指针,创建出的子线程的处理动作,也就是该函数在子线程中执行。
- arg: 作为实参传递到 start_routine 指针指向的函数内部
- 返回值:线程创建成功返回0,创建失败返回对应的错误号
2.2 创建线程
下面是创建线程的示例代码,在创建过程中一定要保证编写的线程函数与规定的函数指针类型一致:void *(*start_routine) (void *):
#include<iostream>
#include<string>
#include <windows.h>
#include<pthread.h>
using namespace std;
// @file:CreateThreading
// @author:IdealSanX_T
// @date:2024/6/