Java教程

网络编程(四)

本文主要是介绍网络编程(四),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

网络编程(四)


昨日内容


UDP协议


import socket  # 服务端
server = socket.socket(type=socket.SOCK_DGRAM)  # 自己指定UDP协议(默认是TCP协议)
server.bind(('127.0.0.1', 8080))  # 和TCP几乎一样,写入地址和端口号
msg, addr = server.recvfrom(1024)  # 待接收
print('msg>>>:', msg.decode('utf8'))
print('addr>>>:', addr)  # 额外打印出端口号,为了确定是哪个客户端
server.sendto(b'hello baby', addr)


import socket  # 客户端
client = socket.socket(type=socket.SOCK_DGRAM)  # 自己指定UDP协议(默认是TCP协议)
server_addr = ('127.0.0.1', 8080)  # 查找通讯录
client.sendto(b'hello server baby', server_addr)
msg, addr = client.recvfrom(1024)
print('msg>>>:', msg.decode('utf8'))
print('addr>>>:', addr)

不同处
	UDP																		 		TCP
socket.socket(type=socket.SOCK_DGRAM)				socket.socket()
recvfrom()																	recv()
sendto()																		send()

操作系统发展史


graph TB 无操作系统-->联机批处理-->脱机批处理

一句话概括操作系统发展史:为了最大的提升CPU的利用率


多道技术

IO操作:IO操作中的读写操作不是我们平时所说读写看,而是将数据加载到硬盘中,我们叫IO流的写操作,即输入流,将硬盘加载出来,叫做IO流的读操作,即输出流。

串行:多个程序依次执行

多道:利用IO操作的间隙:看似多个程序同时执行


进程理论

程序:代码集合体

进程:正在执行的代码集合体

时间片轮转、优先级、多级反馈队列:

这篇博客描述的很好:调度算法——时间片轮转、优先级、多级反馈队列(例题详细!!!)


并发与并行

'''描述的是任务的的工作方式'''

并发:看上去像同时在执行就可以称之为是并发(单个CPU就可以)

并行:必须同一时间同时执行(必须要有多个CPU才可以)

高并发量:1星轨,2星轨······


同步与异步

'''描述的是任务的提交方式'''

同步:提交完任务之后原地等待任务的结果 期间不做任何事(类似串行)

异步: 提交完任务之后不原地等待结果 结果通过反馈机制获取 (类似多道)


阻塞与非阻塞

'''描述的是任务的执行状态'''

阻塞:阻塞态

非阻塞:就绪态 运行态



今日学习内容


代码创建进程

第一种:
from multiprocessing import Process
import time


def task(name):
    print('%s is running' % name)
    time.sleep(3)
    print('%s is over' % name)


if __name__ == '__main__':
    p = Process(target=task, args=('eason',))  # 创建一个进程对象
    p.start()  # 告诉操作系统创建一个新的进程并启动进程中的所有功能
    print('主进程')
  """
强调:不同的操作系统创建进程的要求不一样
    在windows中创建进程是以导入模块的方式进行 所以创建进程的代码必须写在__main__子代码中
    否则会直接报错 因为在无限制创建进程
    在linux和mac中创建进程是直接拷贝一份源代码然后执行 不需要写在__main__子代码中
"""
第二种:
from multiprocessing import Process
import time
class MyProcess(Process):
    def __init__(self, username):  # 重写__init__方法
        self.username = username  # 新增一个参数
        super().__init__()  # 重新调用原始方法
    def run(self):
        print('我是',self.username)
        time.sleep(3)
        print('我也是',self.username)
if __name__ == '__main__':
    p = MyProcess('eason')
    p.start()
    print('主进程')

进程实现并发

'''服务端'''
import socket
from multiprocessing import Process

server = socket.socket()
server.bind(('127.0.0.1', 8080))
server.listen(5)

# 将服务客户端的代码封装成函数(通信代码)
def talk(sock):
    while True:
        data = sock.recv(1024)
        print(data.decode('utf8'))
        sock.send(data.upper())

if __name__ == '__main__':
    while True:
        sock, addr = server.accept()
        p = Process(target=talk, args=(sock, ))
        p.start()

'''客户端'''
import socket

client = socket.socket()
client.connect(('127.0.0.1', 8080))

while True:
    client.send(b'多个客户端不同的消息')
    data = client.recv(1024)
    print(data.decode('utf8'))

join方法

from multiprocessing import Process
import time


def task(name, n):
    print(f'{name} is running')
    time.sleep(n)
    print(f'{name} is over')


if __name__ == '__main__':
    p1 = Process(target=task, args=('jason', 1))
    p2 = Process(target=task, args=('tony', 2))
    p3 = Process(target=task, args=('kevin', 3))
    start_time = time.time()
    p1.start()  # 调用一个工作一秒的对象
    p2.start()	# 调用一个工作两秒的对象
    p3.start()	# 调用一个工作三秒的对象
    p1.join()	# 结束一个工作进程
    p2.join()	# 结束一个工作进程
    p3.join()	# 结束一个工作进程
    end_time = time.time() - start_time  # 计算三个进程都工作完的时间
    print('主进程', f'总耗时:{end_time}')  # 主进程 总耗时:三秒
    因为三个工作进程是并发启动的,总共用时取决于时间最长的那个
    
注意:    
  	如果是一个start一个join交替执行 那么总耗时就是各个任务耗时总和
    因为每项工作执行完后才会继续下一项工作

进程间数据默认隔离

# 内存可以看成是有很多个小隔间组成的 彼此不干扰
from multiprocessing import Process

money = 999

def task():
    global money  # 局部修改全局不可变类型
    money = 666

if __name__ == '__main__':
    p = Process(target=task)
    p.start()
    p.join()  # 确保子进程代码运行结束再打印money
    print(money)
 
"""默认隔离  但是可以通过一些技术打破"""

进程对象属性

1.查看进程号的方法
	1.1.current_process函数
  	from multiprocessing import Process, current_process
    current_process().pid
 	# 获取进程号的用处之一就是可以通过代码的方式管理进程
  	windows  			taskkill关键字
    mac/linux  		kill关键字
  1.2.os模块
  	os.getpid()  # 获取当前进程的进程号
    os.getppid()  # 获取当前进程的父进程号
2.杀死子进程
	terminate()
3.判断子进程是否存活
	is_alive()

僵尸进程与孤儿进程

僵尸进程:终止主进程时,主进程会默认等待子进程结束才会结束

所有子进程在运行结束之后就会变成僵尸进程,因为没有主进程去接受这个子进程了

这写子进程短时间保留着pid和一些运行过程的中的记录便于主进程查看

这些信息会被主进程回收

  1. 主进程正常结束
  2. 调用join方法

孤儿进程:子进程存活着 父进程意外死亡,子进程会被系统自动接管


亚索路过~


守护进程

"""
守护即死活全部参考守护的对象
	对象死立刻死
"""
from multiprocessing import Process
import time


def task(name):
    print(f'主进程{name}启动')
    time.sleep(3)
    print(f'主进程{name}结束了')

if __name__ == '__main__':
    p = Process(target=task, args=('子进程',))
    # 必须写在start前面
    # p.daemon = True  # 将子进程设置为守护进程:主进程结束 子进程立刻结束
    p.start()
    print('主进程结束了')
    
结果:
主进程结束了
主进程子进程启动
主进程子进程结束了
主进程被结束但是子进程还是继续运行到结束

from multiprocessing import Process
import time	


def task(name):
    print(f'主进程{name}启动')
    time.sleep(3)
    print(f'主进程{name}结束了')

if __name__ == '__main__':
    p = Process(target=task, args=('子进程',))
    # 必须写在start前面
    p.daemon = True  # 将子进程设置为守护进程:主进程结束 子进程立刻结束
    p.start()
    print('主进程结束了')
    
结果:
主进程结束了

主进程被杀死

互斥锁

from multiprocessing import Process, Lock
mutex = Lock()
mutex.acquire()  # 抢锁
mutex.release()  # 放锁

针对互斥锁

	
这篇关于网络编程(四)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!