宁波住房建设局网站,网站移动端流量,巨野网站定制,wordpress文章添加字段文章目录 一、线程与进程的概念#xff1a;二、多线程实现三、线程锁四、线程数量的设置 一、线程与进程的概念#xff1a;
简单理解 假设总共有3个孩子需要喂饭#xff0c;孩子每吃一口饭需要咀嚼消化一下。 多线程方案#xff1a; 雇佣1个保姆#xff0c;在喂A孩子吃饭… 文章目录 一、线程与进程的概念二、多线程实现三、线程锁四、线程数量的设置 一、线程与进程的概念
简单理解 假设总共有3个孩子需要喂饭孩子每吃一口饭需要咀嚼消化一下。 多线程方案 雇佣1个保姆在喂A孩子吃饭等到他开始咀嚼的时候开始喂第二个孩子等到第二个孩子开始咀嚼的时候开始喂第三个孩子。 多进程方案 雇佣3个保姆3个保姆分别喂3个孩子。
线程与进程的概念
进程是资源的分配和调度的独立单元。进程拥有完整的虚拟地址空间当发生进程切换时不同的进程拥有不同的虚拟地址空间。而同一进程的多个线程共享同一地址空间不同进程之间的线程无法共享线程是CPU调度的基本单元一个进程包含若干线程至少一个线程。线程比进程小基本上不拥有系统资源。线程的创建和销毁所需要的时间比进程小很多由于线程之间能够共享地址空间因此需要考虑同步和互斥操作一个线程的意外终止会影响整个进程的正常运行但是一个进程的意外终止不会影响其他的进程的运行。因此多进程程序安全性更高。
总之多进程程序安全性高进程切换开销大效率低多线程程序维护成本高线程切换开销小效率高。
并发 指在同一时间段内有多个任务在交替执行。在多任务操作系统中多个任务可以在同一时间共享CPU因此表现出来的是并发执行的状态。这种情况下多个任务的执行是交替进行的每个任务都会分配到一定的时间片来执行直到任务完成或者时间片用完。
并发可以提高系统的吞吐量和资源利用率因为在同一时间段内多个任务可以同时执行从而提高CPU的利用率和系统的响应速度。但是在并发执行中由于CPU时间片的切换和任务间的上下文切换等开销会降低系统的效率增加系统的负担。此外如果多个任务之间存在资源争用的情况还需要采用同步机制来保证资源的正确性。
并行 是指在同一时间段内有多个任务同时执行。在多处理器系统中不同的处理器可以同时执行不同的任务因此表现出来的是并行执行的状态。这种情况下不同的处理器可以同时执行不同的任务从而提高系统的性能和效率。
并行可以进一步提高系统的性能和吞吐量因为不同的任务可以同时执行而不需要等待其他任务的完成。这可以使得系统的处理能力得到充分的发挥从而提高系统的响应速度和吞吐量。但是在并行执行中如果任务之间存在资源争用的情况需要采用同步机制来保证资源的正确性和一致性。
并发与并行的区别 多线程在单核CPU上表现为并发因为虽然多个线程同时执行但在微观层面上仍然是交替执行的。然而在多核CPU上多线程可以并行执行因为它们可以在不同的核心上同时执行。
多进程则不同它们通常在多核或多CPU的计算机上并行执行。多进程是实现并行处理的有效方式因为它们可以将任务分配到不同的CPU核心上从而实现真正的并行处理。
二、多线程实现
线程的执行是由CPU进行调度的一个CPU在同一时刻只会执行一个线程我们看上去的线程A 和 线程B并发执行。
为了让用户感觉这些任务正在同时进行操作系统利用了时间片轮转的方式CPU给每个任务都服务一定的时间然后把当前任务的状态保存下来在加载下一任务的状态后继续服务下一任务。任务的状态保存及再加载这段过程就叫做上下文切换。
Python中通过threading模块就可以很好地实现多线程下面是一个简单的例子
import threading
import time# 在这里是每一个线程函数
def loop_func(i, sec):print(This is {} loop..format(i))logging.warning(f{i},{sec})logging.info(f{i},{sec})time.sleep(sec)print(The {} loop finished..format(i))def main():l [10, 20, 15] # 每个函数的循环时间这里可以调整为不同线程的参数池ts []for i in range(len(l)):# 实例化3个Thread对象target指定调用的函数args指定传给loop_func的参数thread threading.Thread(targetloop_func, args(i, l[i]))ts.append(thread)for i in range(len(l)):ts[i].start() # 启动线程for i in range(len(l)):ts[i].join() # 阻塞线程使得主线程等到所有的子线程完成后再退出结束print(Main Thread Finished)if __name__ __main__:start_time time.time()main()end_time time.time()print(耗时{:.2f}秒.format(end_time - start_time))这里有4个重要的地方
线程函数的编写此处为loop_func通过threading.Thread()方法实例化线程通过start()方法启动线程通过.join()方法阻塞线程使得主线程等到所有的子线程完成后再退出结束
需要注意的是多线程的执行顺序是不确定的线程的启动顺序不一定等于线程的执行顺序。
三、线程锁
线程锁Tread Lock) 是一种同步机制用于解决多线程访问共享资源可能出现的并发问题。在多线程环境下多个线程对共享资源的访问可能导致数据不一致或其他不可预测的结果。线程锁通过对共享资源的访问进行控制确保每一时刻只有一个线程能够访问共享资源从而避免并发问题的产生。
线程锁的主要作用是保护共享资源确保多个线程能够安全地访问共享资源。在多线程环境下如果没有使用线程锁可能会出现以下几种并发问题。
数据竞争(Data Race)多个线程同时读写共享资源导致共享资源的值不确定或无法预测的结果。数据竞争是一种常见的线程安全问题使用线程锁可以避免数据竞争的发生。在计算机操作系统中所谓的I/O就是 输入Input和输出Output也可以理解为读Read和写Write)针对不同的对象I/O模式可以划分为磁盘IO模型和网络IO模型。通常磁盘IO是容易出现数据竞争的请求。同时在写入磁盘的死锁(DeadLock)、饿死Starvation)等并发问题。
import threading# 共享资源
count 0# 创建互斥锁
lock threading.Lock()def increment():global count# 获取锁lock.acquire()try:# 修改共享资源count 1finally:# 释放锁lock.release()# 创建多个线程并启动
threads []
for _ in range(10):thread threading.Thread(targetincrement)threads.append(thread)thread.start()# 等待所有线程结束
for thread in threads:thread.join()# 打印结果
print(Count:, count)四、线程数量的设置
业务中存在大量的网络IO与磁盘IO这些流程是十分耗时的。线程在IO处理的时候CPU就空闲出来利用率不高但并不是线程设置越多越好
关于线程数量的设定该博客讲解地很清晰。 最佳线程数目 线程等待时间线程CPU时间/线程CPU时间 * CPU数目 举例服务器CPU核数为4核一个任务线程cpu耗时为20ms线程等待网络IO、磁盘IO耗时80ms那最佳线程数目( 80 20 )/20 * 4 20。也就是设置20个线程数最佳。
CPU密集型操作内存处理的业务一般线程数设置为CPU核数 1 或者 CPU核数*2。核数为4的话一般设置 5 或 8IO密集型文件操作网络操作数据库操作一般线程设置为cpu核数 / (1-0.9)核数为4的话一般设置 40 https://blog.csdn.net/Rocky006/article/details/131655179 https://wenku.baidu.com/view/ab6ac3a2ac45b307e87101f69e3143323968f5d7.html https://zhuanlan.zhihu.com/p/296796074