一.线程
进程
进程是指正在运行的一个程序。每个进程都有自己的内存空间、代码、数据和文件句柄等资源,进程之间相互独立,互不干扰,通过操作系统的调度,可以让多个进程在同一个计算机上同时运行。在操作系统中,进程是系统资源的分配单位,操作系统通过对进程的资源分配和管理来保证计算机系统的稳定性和安全性。
简单来说进程就是资源单位,表示一个内存空间。
一个只能干一件事情,如果多了那么进程将无能为力。
线程引入
线程是操作系统中的一项基本概念,指的是操作系统能够进行调度和执行的最小单位。线程通常与进程相关联,每个进程都至少有一个线程,也可以创建多个线程来执行不同的任务。线程共享进程的资源,如内存、打开的文件和网络连接等,因此线程之间能够相互通信和共享数据。线程是多任务处理的基础,它能够使计算机同时执行多个任务,提高系统的效率和响应速度。
进程与线程的区别
1. 地址与其他资源(打开文件):进程间相互独立,同一进程的各线程之间共享,
某进程之间的线程不可见
2. 通信:进程间通信IPC,线程间可以直接读写进程数据段(如全局变量)来进行通信——需要进程同步和互斥手段的辅助,以保证数据的一致性。
3.调度和切换:线程上下文切换比进程上下文切换要快得多。(创建进程要申请内存空间,但是线程是在申请好的内存空间直接创建,所以创建进程消耗是要远远大于线程的)
4. 在多线程操作系统中,进程不是一个可执行的实体。
5.资源的消耗对比:进程---线程---协程,单个cpu只能执行一任务
线程的特点
在多线程的操作系统中,一个线程可以有多个进程,每个单位都是以cpu作为利用单位是花费最小的开销实体。
线程中的实体基本不拥有系统资源,只是有一点必不可少的,能保证独立运行的资源
在多线程系统中,线程是独立运行的基本单位,独立调度与分派的基本单位。
线程在统一进程中,可以共享资源,所有的线程都具有相同的id,意味着线程可以访所有进程中的内存资源。
可以并发执行,在一个进程中的多个线程是可以并发执行的,甚至可以在一个进程中执行所有的线程,不进程中的线程同样也可以同时并发执行。
进程调度算法
首先我们了解CPU的工作机制:
1. 遇到 I/O 的时候,会交出执行权限
2.当CPU遇到耗时比较长时,会自动交出执行权限从而执其他的任务
I/O密集型:他会被时间给阻塞,不会占用大量的cpu资源
计算密集型:是指需要大量计算资源来执行的任务,会占用大量的cpu资源
一、先来先服务调度算法
二、短作业优先调度算法
三、时间片轮转法
四、多级反馈队列
进程的并发与并发概念
当CPU为单核时,将只能执行一个任务,不能同时执行多个任务。
当CPU为多核时,可以同时执行多个任务2核可以同时执行两个任务,4核就是同时执行四个任务
并行:统一时刻同时运行
并发:一段时间内是同时运行
如果CPU是单核的,听歌,看视频浏览网页是可以一起操作的,是因为切换CPU做到的。
同步异步阻塞和非阻塞
同步:每一次的运行结果都要依赖于上一步的结果
异步:每次运行的结果不用考虑上一次的结果
执行效率最高的是异步+非阻塞
执行效率最低的是同步+阻塞
二. 如何创建进程
from multiprocessing import Process
def task():
with open('a.txt', 'w', encoding='utf-8')as f:
f.write('helloworld')
"""当前代码并没有开启线程"""
if __name__ == '__main__':
p = Process(target=task) # 实例化出来应该进程类,让这个进程执行task任务
p.start() # 真正的开启了进程
Process类的参数
from multiprocessing import Process
def task(name, age, gender):
print(name, age, gender)
with open('a.txt', 'w', encoding='utf-8')as f:
f.write('helloworld')
"""当前代码并没有开启线程
在windows系统中必须写在里面"""
if __name__ == '__main__':
p = Process(target=task, args=(), kwargs={'name': 'kk', 'age': 18, 'gender': 'male'}) # 实例化出来应该进程类,让这个进程执行task任务
p.start() # 真正的开启了进程
print(p.name)
p.name = '新的命名'
print(p.name)
Process类的几个方法
查看子进程号
关键字pid
from multiprocessing import Process
def task(name, age, gender):
print(name, age, gender)
with open('a.txt', 'w', encoding='utf-8')as f:
f.write('helloworld')
"""当前代码并没有开启线程
在windows系统中必须写在里面"""
if __name__ == '__main__':
p = Process(target=task, args=(), kwargs={'name': 'kk', 'age': 18,
'gender': 'male'}) # 实例化出来应该进程类,让这个进程执行task任务
p.start() # 真正的开启了进程
print(p.pid) # 12048
更改进程名:
p.name = '新的命名'
print(p.name)
p.join() # 子进程的所有代码执行完毕之后再走主进程
print('主进程执行完毕')
结束程序
"""杀死进程,结束程序"""
p.terminate()
三. 如何开启多线程
同步:
from multiprocessing import Process
import time
def task(name):
print('子进程')
time.sleep(2)
if __name__ == '__main__':
start_time = time.time()
for i in range(5):
p = Process(target=task, kwargs={'name': '11'})
p.start()
p.join()
print('总进程时间', time.time()-start_time)
"""输出结果:子进程
子进程
子进程
子进程
子进程
总进程时间 10.242844343185425"""
异步:
from multiprocessing import Process
import time
def task(name):
print('子进程')
time.sleep(2)
if __name__ == '__main__':
start_time = time.time()
ll = []
for i in range(5):
p = Process(target=task, kwargs={'name': '11'})
p.start()
ll.append(p)
for j in ll:
j.join()
print('总进程时间', time.time()-start_time)
"""输出结果
子进程
子进程
子进程
子进程
子进程
总进程时间 2.0766234397888184
总进程时间 2.0766234397888184
总进程时间 2.0766234397888184
总进程时间 2.0766234397888184
总进程时间 2.0766234397888184
"""
基于TCP协议的高并发程序
服务端:
import socket
from multiprocessing import Process
def task(conn):
while True:
try:
data = conn.recv(1024)
if len(data) == 0:
continue
print(data)
conn.send(data.upper())
except Exception as e:
print(e)
break
conn.close()
if __name__ == '__main__':
server = socket.socket()
server.bind(('127.0.0.1', 2000))
server.listen(2)
print('正在接受客户端信息')
while True:
conn, cilent_addr = server.accept() # # 接收, 程序启动之后,会在accept这里夯住,阻塞
p = Process(target=task, args=(conn,))
p.start()
客户端:
import socket
from socket import AF_INET
client = socket.socket(family=AF_INET, type= socket.SOCK_STREAM)
client.connect(('127.0.0.1', 2000))
while True:
data1 = input('请输入法搜服务端的信息')
if len(data1) == 0:
print('请输入正确的信息')
continue
client.send(data1.encode('utf-8'))
data = client.recv(1024)
client.close()