当前位置: 首页 > news >正文

python----线程、进程、协程的区别及多线程详解

文章目录

    • 一、线程、进程、协程区别
    • 二、创建线程
      • 1、函数创建
      • 2、类创建
    • 三、线程锁
      • 1、Lock
      • 2、死锁
        • 2.1加锁之后处理业务逻辑,在释放锁之前抛出异常,这时的锁没有正常释放,当前的线程因为异常终止了,就会产生死锁。
        • 2.2开启两个或两个以上的线程,不同的线程得到了不同的锁,都在等待对方释放锁,但是都在阻塞,所以产生了死锁
        • 2.3在同一线程里,多次取获得锁,第一次获取锁后,还未释放,再次获得锁
      • 3、RLock
    • 四、线程通信
      • 1、condition
      • 2、semaphore

一、线程、进程、协程区别

1. 进程是资源分配的独立单位,是应用程序的载体, 进程之间是相互独立(资源不共享),一个进程由多个线程构成2.线程是资源分配的最小单位,线程共享进程的资源3.协程是用户态执行的轻量级编程模型,由单一线程内部发出控制信号进行调度,协程允许不同入口点在不同的位置暂停或开始程序,协程本质就是一个小线程多线程适合于 I/O 密集型任务,如网络请求、文件读写等,可以提高并发性和响应性。
多进程适用于 CPU 密集型任务,如大量计算、图像处理等,可以利用多核处理器加速运算。

二、创建线程

在Python中创建线程主要依靠内置的threading模块。线程类Thread的常用方法如下表:

序号方法含义
1start()创建一个Thread子线程实例并执行该实例的run()方法
2run()子线程需要执行的目标任务
3join()主进程阻塞等待子线程直到子线程结束才继续执行,可以设置等待超时时间timeout
4is_alive()判断子线程是否终止
5daemon()设置子线程是否随主进程退出而退出,默认是False

threading.current_thread():获取到当前线程。

获取线程后可以得到两个比较重要的属性:name和ident,分别是线程名称和id。

创建线程可以使用两种方法:使用函数或类创建。

1、函数创建

import threading
import timedef myThread(i):start = time.time()my_thread_name = threading.current_thread().name  # 当前线程的名字time.sleep(i)my_thread_id = threading.current_thread().ident  # 当前线程idprint('当前线程为:{},线程ID:{},所在进程为:{}'.format(my_thread_name, my_thread_id, os.getpid()))print('%s线程运行时间结束,耗时%s...' % (my_thread_name, time.time() - start))# 创建三个线程
def fun():t1 = time.time()thread = []for i in range(1, 4):t = threading.Thread(target=myThread,name='线程%s' % i, args=(i,))t.start()thread.append(t)for i in thread:i.join()  # 阻塞主线程if __name__ == '__main__':fun()
threading.Thread(group=None,target=None,name='',args=(),kwargs={},daemon=False)
group:预留参数,不需要传递
target:目标代码(要执行的内容)
name:线程名称:字符串
args:是target的参数,可迭代对象
kwargs:是target的参数,是一个字典
daemon:设置线程为守护线程

2、类创建

class myThread(threading.Thread):def __init__(self,name=None):super().__init__()self.name = namedef run(self):start = time.time()my_thread_name = threading.current_thread().name  # 当前线程的名字time.sleep(3)my_thread_id = threading.current_thread().ident  # 当前线程idprint('当前线程为:{},线程ID:{},所在进程为:{}'.format(my_thread_name, my_thread_id, os.getpid()))print('%s线程运行时间结束,耗时%s...' % (my_thread_name, time.time() - start))# 创建三个线程
def fun():t1 = time.time()thread = []for i in range(1, 4):t = myThread(name='线程%s' % i)t.start()thread.append(t)for i in thread:i.join()  # 阻塞主线程,直到子线程执行完毕再运行主线程if __name__ == '__main__':fun()

三、线程锁

多线程一个很大的问题是数据不安全,因为线程之间的数据是共享的。多线程可以通过线程锁来进行数据同步,可用于保护共享资源同时被多个线程读写引起冲突导致错误

import threading
x = 0
# lock = threading.RLock()
def increment():global xname = threading.current_thread().namefor _ in range(1000000):x += 1print(name, x)
threads = []
for _ in range(3):t = threading.Thread(target=increment)threads.append(t)t.start()
for t in threads:t.join()
print("Final value of x:", x)#Thread-2 1435674
#Thread-1 1423093
#Thread-3 1727936
#;Final value of x: 1727936

可以看出开启三个线程在0的基础上每次加1000000得到的结果应该是3000000.但不是这样的

1、Lock

线程同步能够保证多个线程安全访问竞争资源,最简单的同步机制是引入互斥锁。互斥锁为资源设置一个状态:锁定和非锁定。某个线程要更改共享数据时,先将其锁定,此时资源的状态为“锁定”,其他线程不能更改;直到该线程释放资源,将资源的状态变成“非锁定”,其他的线程才能再次锁定该资源。互斥锁保证了每次只有一个线程进行写入操作,从而保证了多线程情况下数据的正确性。

import threading
x = 0
lock = threading.Lock()
def increment():global xname = threading.current_thread().namelock.acquire()try:for _ in range(1000000):x += 1print(name, x)finally:lock.release()
threads = []
for _ in range(3):t = threading.Thread(target=increment)threads.append(t)t.start()for t in threads:t.join()
print("Final value of x:", x)#Thread-1 1000000
#Thread-2 2000000
#Thread-3 3000000
#Final value of x: 3000000

使用了锁之后,代码运行速度明显降低,这是因为线程由原来的并发执行变成了串行,不过数据安全性得到保证。

还可以使用with lock这种上下文格式,自动管理上锁和释放锁。

import threading
x = 0
lock = threading.Lock()
def increment():global xname = threading.current_thread().namewith lock:for _ in range(1000000):x += 1print(name, x)
threads = []
for _ in range(3):t = threading.Thread(target=increment)threads.append(t)t.start()
for t in threads:t.join()
print("Final value of x:", x)#Thread-1 1000000
#Thread-2 2000000
#Thread-3 3000000
#Final value of x: 3000000
一般来说加锁以后还要有一些功能实现,在释放之前还有可能抛异常,一旦抛出异常,锁是无法释放,但是当前线程可能因为这个异常被终止了,这就产生了死锁。死锁解决办法:
1、使用 try..except..finally 语句处理异常、保证锁的释放2、with 语句上下文管理,锁对象支持上下文管理。只要实现了__enter__和__exit__魔术方法的对象都支持上下文管理。另一种是
锁的应用场景:独占锁: 锁适用于访问和修改同一个共享资源的时候,即读写同一个资源的时候。共享锁: 如果共享资源是不可变的值时,所有线程每一次读取它都是同一样的值,这样的情况就不需要锁。使用锁的注意事项:少用锁,必要时用锁。使用了锁,多线程访问被锁的资源时,就变成了串行,要么排队执行,要么争抢执行。
加锁时间越短越好,不需要就立即释放锁。
一定要避免死锁。
不使用锁时,有了效率,但是结果是错的。使用了锁,变成了串行,效率地下,但是结果是对的。

2、死锁

2.1加锁之后处理业务逻辑,在释放锁之前抛出异常,这时的锁没有正常释放,当前的线程因为异常终止了,就会产生死锁。
解决方案:
1、使用 try..except..finally 语句处理异常、保证锁的释放2、with 语句上下文管理,锁对象支持上下文管理。只要实现了__enter__和__exit__魔术方法的对象都支持上下文管理。
2.2开启两个或两个以上的线程,不同的线程得到了不同的锁,都在等待对方释放锁,但是都在阻塞,所以产生了死锁
解决方案:
1、不同线程中获得锁的顺序一致,不能乱2、使用递归锁:RLock。
2.3在同一线程里,多次取获得锁,第一次获取锁后,还未释放,再次获得锁
解决方案:
1、使用递归锁:RLock。

3、RLock

递归锁也被称为“锁中锁”,指一个线程可以多次申请同一把锁,但是不会造成死锁,这就可以用来解决上面的死锁问题。

import threading
x = 0
lock = threading.RLock()
def increment():global xname = threading.current_thread().namelock.acquire()lock.acquire()try:for _ in range(1000000):x += 1print(name, x)finally:lock.release()lock.release()
threads = []
for _ in range(3):t = threading.Thread(target=increment)threads.append(t)t.start()
for t in threads:t.join()
print("Final value of x:", x)#Thread-1 1000000
#Thread-2 2000000
#Thread-3 3000000
#Final value of x: 3000000

RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次acquire。直到一个线程所有的acquire都被release,其他的线程才能获得资源。

四、线程通信

1、condition

Condition可以认为是一把比Lock和RLOK更加高级的锁,其在内部维护一个琐对象(默认是RLock),可以在创建Condigtion对象的时候把琐对象作为参数传入。Condition也提供了acquire, release方法,其含义与琐的acquire, release方法一致,其实它只是简单的调用内部琐对象的对应的方法而已。

运行原理:可以认为Condition对象维护了一个锁(Lock/RLock)和一个waiting池。线程通过acquire获得Condition对象,当调用wait方法时,线程会释放Condition内部的锁并进入blocked状态,同时在waiting池中记录这个线程。当调用notify方法时,Condition对象会从waiting池中挑选一个线程,通知其调用acquire方法尝试取到锁。Condition对象的构造函数可以接受一个Lock/RLock对象作为参数,如果没有指定,则Condition对象会在内部自行创建一个RLock。除了notify方法外,Condition对象还提供了notifyAll方法,可以通知waiting池中的所有线程尝试acquire内部锁。由于上述机制,处于waiting状态的线程只能通过notify方法唤醒,所以notifyAll的作用在于防止有的线程永远处于沉默状态。
import threading
import time
from queue import Queueclass Producer(threading.Thread):# 生产者函数def run(self):global countwhile True:if con.acquire():# 当count 小于等于1000 的时候进行生产if count > 1000:con.wait()else:count = count + 100msg = self.name + ' produce 100, count=' + str(count)print(msg)# 完成生成后唤醒waiting状态的线程,# 从waiting池中挑选一个线程,通知其调用acquire方法尝试取到锁con.notify()con.release()time.sleep(1)class Consumer(threading.Thread):# 消费者函数def run(self):global countwhile True:# 当count 大于等于100的时候进行消费if con.acquire():if count < 100:con.wait()else:count = count - 5msg = self.name + ' consume 5, count=' + str(count)print(msg)con.notify()# 完成生成后唤醒waiting状态的线程,# 从waiting池中挑选一个线程,通知其调用acquire方法尝试取到锁con.release()time.sleep(1)count = 0
con = threading.Condition()def test():for i in range(2):p = Producer()p.start()for i in range(5):c = Consumer()c.start()
if __name__ == '__main__':test()#Thread-1 produce 100, count=100
#Thread-2 produce 100, count=200
#Thread-3 consume 5, count=195
#Thread-4 consume 5, count=190
#Thread-5 consume 5, count=185
#Thread-6 consume 5, count=180
#Thread-7 consume 5, count=175
#Thread-2 produce 100, count=275
#Thread-3 consume 5, count=270

2、semaphore

semaphore是python中的一个内置的计数器,内部使用了Condition对象,多线程同时运行,能提高程序的运行效率,但是并非线程越多越好,而 semaphore 信号量可以通过内置计数器来控制同时运行线程的数量,启动线程(消耗信号量)内置计数器会自动减一,线程结束(释放信号量)内置计数器会自动加一;内置计数器为零,启动线程会阻塞,直到有本线程结束或者其他线程结束为止;
创建多个线程,同一时间运行三个线程

import threading
# 导入时间模块
import time# 添加一个计数器,最大并发线程数量5(最多同时运行5个线程)
semaphore = threading.Semaphore(2)def foo():semaphore.acquire()    #计数器获得锁time.sleep(2)   #程序休眠2秒print("当前时间:",time.ctime()) # 打印当前系统时间semaphore.release()    #计数器释放锁if __name__ == "__main__":thread_list= list()for i in range(6):t=threading.Thread(target=foo,args=()) #创建线程thread_list.append(t)t.start()  #启动线程for t in thread_list:t.join()print("程序结束!")#当前时间: Tue Jul 30 11:18:38 2024
#当前时间: Tue Jul 30 11:18:38 2024
#当前时间: Tue Jul 30 11:18:40 2024
#当前时间: Tue Jul 30 11:18:40 2024
#当前时间: Tue Jul 30 11:18:42 2024
#当前时间: Tue Jul 30 11:18:42 2024
#程序结束!

因为Semaphore使用了Condition,线程之间仍然有锁保证线程数据安全

相关文章:

python----线程、进程、协程的区别及多线程详解

文章目录 一、线程、进程、协程区别二、创建线程1、函数创建2、类创建 三、线程锁1、Lock2、死锁2.1加锁之后处理业务逻辑&#xff0c;在释放锁之前抛出异常&#xff0c;这时的锁没有正常释放&#xff0c;当前的线程因为异常终止了&#xff0c;就会产生死锁。2.2开启两个或两个…...

将 magma example 改写成 cusolver example eqrf

1&#xff0c;简单安装Magma 1.1 下载编译 OpenBLAS $ git clone https://github.com/OpenMathLib/OpenBLAS.git $ cd OpenBLAS/ $ make -j DEBUG1 $ make install PREFIX/home/hipper/ex_magma/local_d/OpenBLAS/1.2 下载编译 magma $ git clone https://bitbucket.org/icl…...

微信小程序教程007:数据绑定

文章目录 数据绑定1、数据绑定原则2、在data中定义页面数据3、Mustache语法的格式4、Mustache应用场景5、绑定属性6、三元运算8、算数运算数据绑定 1、数据绑定原则 在data中定义数据在WXML中使用数据2、在data中定义页面数据 在页面对应的.js文件中,把数据定义到data对象中…...

Git -- git stash 暂存

使用 git 或多或少都会了解到 git stash 命令&#xff0c;但是可能未曾经常使用&#xff0c;下面简单介绍两种使用场景。 场景一&#xff1a;分支A开发&#xff0c;分支B解决bug 我们遇到最常见的例子就是&#xff0c;在当前分支 A 上开发写需求&#xff0c;但是 B 分支上有…...

基于YOLO的植物病害识别系统:从训练到部署全攻略

基于深度学习的植物叶片病害识别系统&#xff08;UI界面YOLOv8/v7/v6/v5代码训练数据集&#xff09; 1. 引言 在农业生产中&#xff0c;植物叶片病害是影响作物产量和质量的主要因素之一。传统的病害检测方法依赖于人工识别&#xff0c;效率低且易受主观因素影响。随着深度学…...

数据库开发:MySQL基础(二)

MySQL基础&#xff08;二&#xff09; 一、表的关联关系 在关系型数据库中&#xff0c;表之间可以通过关联关系进行连接和查询。关联关系是指两个或多个表之间的关系&#xff0c;通过共享相同的列或键来建立连接。常见的关联关系有三种类型&#xff1a;一对多关系&#xff0c;…...

实现物理数据库迁移到云上

实现物理数据库迁移到云上 以下是一个PHP脚本&#xff0c;用于实现物理数据库迁移到云上的步骤&#xff1a; <?php// 评估和规划 $databaseSize "100GB"; $performanceRequirements "high"; $dataComplexity "medium";$cloudProvider &…...

[Spring] MyBatis操作数据库(进阶)

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…...

【Websim.ai】一句话让AI帮你生成一个网页

【Websim.ai】一句话让AI帮你生成一个网页 网站链接 websim.ai 简介 websim.ai接入了Claude Sonnet 3.5&#xff0c;GPT-4o等常用的LLM&#xff0c;只需要在websim.ai的官网指令栏中编写相关指令&#xff0c;有点类似大模型的Prompt&#xff0c;指令的好坏决定了网页生成的…...

云计算实训16——关于web,http协议,https协议,apache,nginx的学习与认知

一、web基本概念和常识 1.Web Web 服务是动态的、可交互的、跨平台的和图形化的为⽤户提供的⼀种在互联⽹上浏览信息的服务。 2.web服务器&#xff08;web server&#xff09; 也称HTTP服务器&#xff08;HTTP server&#xff09;&#xff0c;主要有 Nginx、Apache、Tomcat 等。…...

2024年必备技能:小红书笔记评论自动采集,零基础也能学会的方法

摘要&#xff1a; 面对信息爆炸的2024年&#xff0c;小红书作为热门社交平台&#xff0c;其笔记评论成为市场洞察的金矿。本文将手把手教你&#xff0c;即便编程零基础&#xff0c;也能轻松学会利用Python自动化采集小红书笔记评论&#xff0c;解锁营销新策略&#xff0c;提升…...

【Gitlab】SSH配置和克隆仓库

生成SSH Key ssh-keygen -t rsa -b 4096 私钥文件: id_rsa 公钥文件:id_rsa.pub 复制生成的ssh公钥到此处 克隆仓库 git clone repo-address 需要进行推送和同步来更新本地和服务器的文件 推送更新内容 git push <remote><branch> 拉取更新内容 git pull &…...

[Day 35] 區塊鏈與人工智能的聯動應用:理論、技術與實踐

區塊鏈的分布式存儲技術 區塊鏈技術自2008年比特幣白皮書發表以來&#xff0c;已經成為一種革命性的技術&#xff0c;帶來了許多創新。區塊鏈本質上是一個去中心化的分布式賬本&#xff0c;每個節點都持有賬本的副本&#xff0c;並參與記錄和驗證交易。分布式存儲是區塊鏈的重…...

Vue 3 中使用 inMap.js 实现蜂窝热力图的可视化

本文由ScriptEcho平台提供技术支持 项目地址&#xff1a;传送门 Vue 3 中使用 inMap.js 实现蜂窝热力图的可视化 应用场景介绍 蜂窝热力图是一种可视化技术&#xff0c;用于在地图上显示数据的分布情况。它将数据点划分为六边形单元格&#xff0c;并根据单元格内数据的密度…...

nginx隐藏server及版本号

1、背景 为了提高nginx服务器的安全性&#xff0c;降低被攻击的风险&#xff0c;需要隐藏nginx的server和版本号。 2、隐藏nginx版本号 在 http {—}里加上 server_tokens off; 如&#xff1a; http {……省略sendfile on;tcp_nopush on;keepalive_timeout 60;tcp_nodelay o…...

Oracle DBMS_XPLAN包

DBMS_XPLAN 包的解释和关键点 DBMS_XPLAN 包是 Oracle 数据库中一个重要的工具&#xff0c;它允许数据库管理员和开发人员以各种方式显示 SQL 语句的执行计划&#xff0c;这对于 SQL 优化和性能诊断至关重要。以下是主要函数及其描述&#xff1a; 用于显示执行计划的主要函数…...

【ffmpeg命令入门】分离音视频流

文章目录 前言音视频交错存储概念为什么要进行音视频交错存储&#xff1a;为什么要分离音视频流&#xff1a; 去除音频去除视频 总结 前言 FFmpeg 是一款强大的多媒体处理工具&#xff0c;广泛应用于音视频的录制、转换和流媒体处理等领域。它支持几乎所有的音频和视频格式&am…...

小红书笔记评论采集全攻略:三种高效方法教你批量导出

摘要&#xff1a; 本文将深入探讨如何利用Python高效采集小红书平台上的笔记评论&#xff0c;通过三种实战策略&#xff0c;手把手教你实现批量数据导出。无论是市场分析、竞品监测还是用户反馈收集&#xff0c;这些技巧都将为你解锁新效率。 一、引言&#xff1a;小红书数据…...

实战:ZooKeeper 操作命令和集群部署

ZooKeeper 操作命令 ZooKeeper的操作命令主要用于对ZooKeeper服务中的节点进行创建、查看、修改和删除等操作。以下是一些常用的ZooKeeper操作命令及其说明&#xff1a; 一、启动与连接 启动ZooKeeper服务器&#xff1a; ./zkServer.sh start这个命令用于启动ZooKeeper服务器…...

linux运维一天一个shell命令之 top详解

概念&#xff1a; top 命令是 Unix 和类 Unix 操作系统&#xff08;如 Linux、macOS&#xff09;中一个常用的系统监控工具&#xff0c;它提供了一个动态的实时视图&#xff0c;显示系统的整体性能信息&#xff0c;如 CPU 使用率、内存使用情况、进程列表等。 基本用法 root…...

大模型微调:参数高效微调(PEFT)方法总结

PEFT (Parameter-Efficient Fine-Tuning) 参数高效微调是一种针对大模型微调的技术&#xff0c;旨在减少微调过程中需要调整的参数量&#xff0c;同时保持或提高模型的性能。 以LORA、Adapter Tuning 和 Prompt Tuning 为主的PEFT方法总结如下 LORA 论文题目&#xff1a;LORA:…...

Spark+实例解读

第一部分 Spark入门 学习教程&#xff1a;Spark 教程 | Spark 教程 Spark 集成了许多大数据工具&#xff0c;例如 Spark 可以处理任何 Hadoop 数据源&#xff0c;也能在 Hadoop 集群上执行。大数据业内有个共识认为&#xff0c;Spark 只是Hadoop MapReduce 的扩展&#xff08…...

WPF多语言国际化,中英文切换

通过切换资源文件的形式实现中英文一键切换 在项目中新建Language文件夹&#xff0c;添加资源字典&#xff08;xaml文件&#xff09;&#xff0c;中文英文各一个。 在资源字典中写上想中英文切换的字符串&#xff0c;需要注意&#xff0c;必须指定key值&#xff0c;并且中英文…...

Halcon深度学习分类模型

1.Halcon20之后深度学习支持CPU训练模型&#xff0c;没有money买显卡的小伙伴有福了。但是缺点也很明显&#xff0c;就是训练速度超级慢&#xff0c;推理效果也没有GPU好&#xff0c;不过学习用足够。 2.分类模型是Halcon深度学习最简单的模型&#xff0c;可以用在物品分类&…...

洗地机哪种牌子好?洗地机排行榜前十名公布

洗地机市场上品牌琳琅满目&#xff0c;每个品牌都有其独特的魅力和优势。消费者在选择时&#xff0c;往往会根据自己的实际需求、预算以及对产品性能的期望来做出决策。因此&#xff0c;无论是哪个品牌的洗地机&#xff0c;只要能够满足用户的清洁需求&#xff0c;提供便捷的操…...

C++中的虚函数与多态机制如何工作?

在C中&#xff0c;虚函数和多态机制是实现面向对象编程的重要概念。 虚函数是在基类中声明的函数&#xff0c;可以在派生类中进行重写。当基类的指针或引用指向派生类的对象时&#xff0c;通过调用虚函数可以实现动态绑定&#xff0c;即在运行时确定要调用的函数。 多态是指通…...

《LeetCode热题100》---<哈希三道>

本篇博客讲解 LeetCode热题100道中的哈希篇中的三道题。分别是 1.第一道&#xff1a;两数之和&#xff08;简单&#xff09; 2.第二道&#xff1a;字母异位词分组&#xff08;中等&#xff09; 3.第三道&#xff1a;最长连续序列&#xff08;中等&#xff09; 第一道&#xff1…...

秒懂C++之string类(下)

目录 一.接口说明 1.1 erase 1.2 replace&#xff08;最好别用&#xff09; 1.3 find 1.4 substr 1.5 rfind 1.6 find_first_of 1.7 find_last_of 二.string类的模拟实现 2.1 构造 2.2 无参构造 2.3 析构 2.4.【】运算符 2.5 迭代器 2.6 打印 2.7 reserve扩容 …...

github简单地操作

1.调节字体大小 选择options 选择text 选择select 选择你需要的参数就可以了。 2.配置用户名和邮箱 桌面右键&#xff0c;选择git Bash Here git config --global user.name 用户名 git config --global user.email 邮箱名 3.用git实现代码管理的过程 下载别人的项目 git …...

模型改进-损失函数合集

模版 第一步在哪些地方做出修改&#xff1a; 228行 self.use_wiseiouTrue 230行 self.wiou_loss WiseIouLoss(ltypeMPDIoU, monotonousFalse, inner_iouTrue, focaler_iouFalse) 238行 wiou self.wiou_loss(pred_bboxes[fg_mask], target_bboxes[fg_mask], ret_iouFalse…...

C++模板(初阶)

1.引入 在之前的笔记中有提到&#xff1a;函数重载&#xff08;特别是交换函数&#xff08;Swap&#xff09;的实现&#xff09; void Swap(int& left, int& right) {int temp left;left right;right temp; } void Swap(double& left, double& right) {do…...

下面关于Date类的描述错误的一项是?

下面关于Date类的描述错误的一项是&#xff1f; A. java.util.Date类下有三个子类&#xff1a;java.sql.Date、java.sql.Timestamp、java.sql.Time&#xff1b; B. 利用SimpleDateFormat类可以对java.util.Date类进行格式化显示&#xff1b; C. 直接输出Date类对象就可以取得日…...

【Python面试题收录】Python编程基础练习题①(数据类型+函数+文件操作)

本文所有代码打包在Gitee仓库中https://gitee.com/wx114/Python-Interview-Questions 一、数据类型 第一题&#xff08;str&#xff09; 请编写一个Python程序&#xff0c;完成以下任务&#xff1a; 去除字符串开头和结尾的空格。使用逗号&#xff08;","&#…...

C# Nmodbus,EasyModbusTCP读写操作

Nmodbus读写 两个Button控件分别为 读取和写入 分别使用控件的点击方法 ①引用第三方《NModbus4》2.1.0版本 全局 public SerialPort port new SerialPort("COM2", 9600, Parity.None, 8, (StopBits)1); ModbusSerialMaster master; public Form1() port.Open();…...

spark常用参数调优

目录 1.set spark.grouping.sets.reference.hivetrue;2.set spark.locality.wait.rack0s3.set spark.locality.wait0s;4.set spark.executor.memoryOverhead 2G;5.set spark.sql.shuffle.partitions 1000;6.set spark.shuffle.file.buffer 256k7. set spark.reducer.maxSizeInF…...

C#/WinFrom TCP通信+ 网线插拔检测+客服端异常掉线检测

Winfor Tcp通信(服务端) 今天给大家讲一下C# 关于Tcp 通信部分&#xff0c;这一块的教程网上一大堆&#xff0c;不过关于掉网&#xff0c;异常断开连接的这部分到是到是没有多少说明&#xff0c;有方法 不过基本上最多的两种方式&#xff08;1.设置一个超时时间&#xff0c;2.…...

一篇文章掌握Python爬虫的80%

转载&#xff1a;一篇文章掌握Python爬虫的80% Python爬虫 Python 爬虫技术在数据采集和信息获取中有着广泛的应用。本文将带你掌握Python爬虫的核心知识&#xff0c;帮助你迅速成为一名爬虫高手。以下内容将涵盖爬虫的基本概念、常用库、核心技术和实战案例。 一、Python 爬虫…...

【用户会话信息在异步事件/线程池的传递】

用户会话信息在异步事件/线程池的传递 author:shengfq date:2024-07-29 version:1.0 背景: 同事写的一个代码功能,是在一个主线程中通过如下代码进行异步任务的执行,结果遇到了问题. 1.ThreadPool.execute(Runnable)启动一个子线程执行异步任务 2.applicationContext.publis…...

Java8: BigDecimal

Java8:BigDecimal 转两位小数的百分数-CSDN博客 BigDecimal 先做除法 然后取绝对值 在Java 8中&#xff0c;如果你想要对一个BigDecimal值进行除法操作&#xff0c;并随后取其绝对值&#xff0c;你可以通过组合divide方法和abs方法来实现这一目的。不过&#xff0c;需要注意的…...

苹果推送iOS 18.1带来Apple Intelligence预览

&#x1f989; AI新闻 &#x1f680; 苹果推送iOS 18.1带来Apple Intelligence预览 摘要&#xff1a;苹果向iPhone和iPad用户推送iOS 18.1和iPadOS 18.1开发者预览版Beta更新&#xff0c;带来“Apple Intelligence”预览。目前仅支持M1芯片或更高版本的设备。Apple Intellige…...

testRigor-基于人工智能驱动的无代码自动化测试平台

1、testRigor介绍 简单来说&#xff0c;testRigor是一款基于人工智能驱动的无代码自动化测试平台&#xff0c;它能够通过分析应用的行为模式&#xff0c;智能地生成测试用例&#xff0c;并自动执行这些测试&#xff0c;无需人工编写测试脚本。可以用于Web、移动、API和本机桌面…...

hadoop学习(一)

一.hadoop概述 1.1hadoop优势 1&#xff09;高可靠性&#xff1a;Hadoop底层维护多个数据副本&#xff0c;即使Hadoop某个计算元素或存储出现故障&#xff0c;也不会导致数据的丢失。 2&#xff09;高扩展性&#xff1a;在集群间分配任务数据&#xff0c;可方便扩展数以千计…...

Linux性能监控:sar的可视化方案

在当今的IT环境中&#xff0c;系统性能监控是确保应用程序稳定运行和快速响应问题的关键。Linux作为一种广泛使用的操作系统&#xff0c;拥有多种性能监控工具&#xff0c;其中sar&#xff08;System Activity Reporter&#xff09;因其全面性和灵活性被广泛采用。然而&#xf…...

如何录制电脑屏幕视频,5招让您成为电脑录制高手

在今天&#xff0c;屏幕录制成为每个电脑使用者都应掌握的基础技能。不论是教学分享、会议记录还是游戏直播&#xff0c;屏幕录制都能帮你捕捉那些重要的瞬间&#xff0c;将无形的信息转化为有形的视频。那么&#xff0c;如何录制电脑屏幕视频呢&#xff1f;今天&#xff0c;我…...

AI届的新宠:小语言模型(SLM)?

大语言模型&#xff08;LLM&#xff09;在过去几年产生了巨大影响&#xff0c;特别是随着OpenAI的ChatGPT的出现&#xff0c;各种大语言模型如雨后春笋般出现&#xff0c;国内如KimiChat、通义千问、文心一言和智谱清言等。 然而&#xff0c;大语言模型通常拥有庞大的参数&…...

PMP模拟题错题本

模拟题A 错题整理 项目经理为一个具有按时完成盈利项目历史记录的组织工作。然而&#xff0c;由于缺乏相关方的支持以及他们未能提供信息&#xff0c;这些项目都经历过问题。若要避免这些问题&#xff0c;项目经理在新项目开始时应该做什么&#xff1f; A. 在启动阶段识别关键…...

Laravel Dusk:点亮自动化测试的明灯

Laravel Dusk&#xff1a;点亮自动化测试的明灯 在Web开发中&#xff0c;确保应用程序的用户体验和功能正确性至关重要。Laravel Dusk是一个强大的浏览器自动化测试工具&#xff0c;它允许开发者模拟用户与应用程序的交互&#xff0c;从而进行端到端的测试。本文将深入探讨Lar…...

Git、Gitlab以及分支管理

分布式版本控制系统 一、Git概述 Git是一种分布式版本控制系统&#xff0c;用于跟踪和管理代码的变更。它由Linus torvalds创建的&#xff0c;最初被设计用于Linux内核的开发。Git 允许开发人员跟踪和管理代码的版本&#xff0c;并且可以在不同的开发人员之间进行协作。 Githu…...

TCP/IP 协议栈介绍

TCP/IP 协议栈介绍 1. 引言 TCP/IP&#xff08;传输控制协议/互联网协议&#xff09;是一组用于数据网络中通信的协议集合&#xff0c;它是互联网的基础。本文将详细介绍TCP/IP协议栈的各个层次、工作原理以及其在网络通信中的作用。 2. TCP/IP 协议栈的层次结构 TCP/IP协议…...

香橙派orangepi系统没有apt,也没有apt-get,也没有yum命令,找不到apt、apt-get、yum的Linux系统

以下是一个关于如何在 Orange Pi 上的 Arch Linux 系统中发现缺失包管理器的问题并解决的详细教程。 发现问题 确认系统类型&#xff1a; 使用以下命令检查当前的 Linux 发行版&#xff1a; uname -a cat /etc/os-release如果你看到类似于 “Arch Linux” 的信息&#xff0c;说…...