多任务介绍
"""
什么是多任务?
操作系统可以同时执行多个任务
现在的操作系统:windows mac os linux unix
这些操作系统 都支持多任务
单核CPU如何实现多任务?
表面看,每个任务都是同时执行,实际上是每个任务在轮询着执行,只是因为CPU的调度太快,导致我们感觉像是所有任务都在同时执行
多核CPU如何实现多任务?
是真正实现了多个任务同时执行
并发:看上去一起执行,任务数大于CPU核心数
并行:一起执行,任务数必须小于等于CPU核心数
实现多任务的方式:
1、多进程方式
2、多线程方式
3、协程方式
4、多进程+多线程
"""
#没有多进程
import time
def func():
while True:
print("this is a process2")
time.sleep(1.5)
if __name__ == '__main__':
while True:
print("this is a process1")
time.sleep(1)
func()
"""
multiprocessing 多进程
"""
from multiprocessing import Process
import time,os
def func(str):
# os.getpid 获取当前进程的进程号
# os.getppid 获取当前进程的父进程
while True:
print("this is process 2--%s--%s--%s"%(str,os.getpid(),os.getppid()))
time.sleep(1.5)
if __name__ == '__main__':
print("父进程启动...--%s--%s"%(os.getpid(),os.getppid()))
# 创建子进程
# target 说明进程的任务
p = Process(target=func,args=("python",))
# 启动进程
p.start()
# 主进程中的
while True:
print("this is a process 1--%s--%s"%(os.getpid(),os.getppid()))
time.sleep(1)
# 让父进程等待子进程结束之后父进程再结束
from multiprocessing import Process
from time import sleep
def func():
print("子进程启动...")
sleep(3)
print("子进程结束...")
if __name__ == '__main__':
print("父进程启动...")
p = Process(target = func)
p.start()
# sleep(1)
# 让父进程等待子进程结束之后父进程再结束
# timeout 超时时间 父进程的等待时间
p.join()
#执行后一直等待
print("父进程结束...")
# 在子进程中修改全局变量 对父进程中的全局变量没有影响
from multiprocessing import Process
num = 100
def run1():
print("孙子进程开始...")
print("孙子进程结束...%s"%(num))
def run():
print("子进程开始...")
global num
num += 1
print(num)
p = Process(target=run1)
p.start()
p.join()
print("子进程结束...")
if __name__ == '__main__':
print("父进程开始...")
p = Process(target=run)
p.start()
p.join()
num += 2
# 在子进程中修改全局变量 对父进程中的全局变量没有影响
# 我们在创建子进程的时候 对全局变量做了一个备份
# 子进程和父进程的Num是两个完全不同的变量
# 所有进程对全局变量的修改 都不会影响其它进程
print("父进程结束...%d"%(num))
#进程池
from multiprocessing import Pool,Process
import time,random
def foo():
print("孙子进程开始...")
print("孙子进程结束...")
def func(name):
print("子进程%s启动..."%(name))
start = time.time()
time.sleep(random.choice([1,2,3]))
end = time.time()
print("子进程%s结束...耗时%.2f"%(name,end - start))
if __name__ == '__main__':
print("父进程开始...")
# 创建进程池
# 如果没有参数 默认大小为自己电脑的CPU核心数
# 表示可以同时执行的进程数量
pp = Pool(2)
for i in range(4):
# 创建进程,放入进程池统一管理
pp.apply_async(func,args=(i,))
# 在调用join之前必须先关掉进程池
# 进程池一旦关闭 就不能再添加新的进程了
pp.close()
# 进程池对象调用join,会等待进程池中所有的子进程结束之后再结束父进程
pp.join()
print("父进程结束...")
多线程
"""
多线程:
在一个进程内部,要同时干很多事,就需要同时执行多个子任务
那么我们把进程内的这些子任务叫做线程
线程的内存空间是共享的 每个线程都共享同一个进程的资源
模块:
1、_thread模块 低级模块
2、threading模块 高级模块 对_thread模块进行了封装
"""
#创建线程
import threading,time
def run(num):
print("子线程%s开始..."%(threading.current_thread().name))
time.sleep(2)
print(num)
time.sleep(2)
# current_thread 返回一个当前线程的实例
print("子线程%s结束..."%(threading.current_thread().name))
if __name__ == '__main__':
print("主线程%s启动..."%(threading.current_thread().name))
# 创建子线程
t = threading.Thread(target = run,args = (1,))
t.start()
t.join()
print("主线程%s结束..."%(threading.current_thread().name))
#多线程共享资源
import threading
num = 0
var = 0
def run(n):
global num
for i in range(1000000):
num += n
num -= n
def run1(n):
global var
for i in range(100):
var += n
var -= n
if __name__ == '__main__':
t1 = threading.Thread(target=run,args=(6,))
t2 = threading.Thread(target=run,args=(9,))
t3 = threading.Thread(target=run,args=(5,))
t3.start()
t1.start()
t2.start()
t1.join()
t2.join()
t3.join()
print("num = %s"%(num))
# 互斥锁
import threading
# 创建锁对象
lock = threading.Lock()
num = 0
def run(n):
global num
for i in range(1000000):
# 加锁 为了确保下面代码只能由一个线程从头到尾的执行
# 会阻止多线程的并发执行,所以效率会大大降低
"""
lock.acquire()
try:
num = num - n
num = num + n
finally:
# 解锁
lock.release()
"""
with lock:
num = num + n
num = num - n
if __name__ == '__main__':
t1 = threading.Thread(target=run,args=(6,))
t2 = threading.Thread(target=run,args=(9,))
t1.start()
t2.start()
t1.join()
t2.join()
print("num = %s"%(num))
# 信号量
import threading,time
# 信号量
sem = threading.Semaphore(3)
def run():
with sem:
for i in range(5):
print("%s--%d"%(threading.current_thread().name,i))
time.sleep(1)
if __name__ == '__main__':
for i in range(5):
t = threading.Thread(target=run)
t.start()
# 凑够数量再结束
import threading,time
sem = threading.Semaphore(10)
bar = threading.Barrier(10)# 凑够数量再结束
def run():
# 先使用指定的信号量
with sem:
print("%s--start..."%(threading.current_thread().name))
time.sleep(1)
bar.wait()
print("%s--end..."%(threading.current_thread().name))
if __name__ == '__main__':
for i in range(21):
t = threading.Thread(target=run)
t.start()
网络编程
"""
sock = socket.socket(socket_family,socket_type)
参数:
socket_family
socket.AF_INET 适用网络协议的传播,ipv4
socket.AF_INET6 ipv6
socket.AF_UNIX 使用与 unix 系统内部传输,
socket_type
socket.SOCK_STREAM TCP协议
socket.SOCK_DGRAM UDP 协议
"""
简单的socket 服务
TCP
#服务器
# 导入模块
import socket
# 创建socket对象 ipv4 TCP协议
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 绑定端口和ip ip如果为空的话 那么表示绑定所有ip
# 127.0.0.1 表示本机地址
sock.bind(("",9876))
# 设置监听
sock.listen(3)
print("服务器已经启动....")
# 接收消息 进入被动阻塞式接受
# con接收sock对象 add接收ip和端口号
con,add = sock.accept()
print(con)
print(add)
print("%s 已经连接成功..."%(add[0]))
recvs = con.recv(512)
print(recvs.decode("utf-8"))
sends = input(">>>>")
con.send(sends.encode("utf-8"))
sock.close()
#客户
import socket
# 必须和服务端的协议保持一致
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 连接服务器
sock.connect(("127.0.0.1",9876))
# 发送消息
sends = input(">>>>")
sock.send(sends.encode("utf-8"))
# 接收消息
recvs = sock.recv(512)
print(recvs.decode("utf-8"))
sock.close()
UDP
#服务器
import socket
# 创建socket对象 ipv4 UDP协议
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
sock.bind(("",8010))
print("服务器已经启动....")
while True:
# con 接收传输过来的数据
# add ip和端口号
con,add = sock.recvfrom(512)
print(con)
print(add)
print("%s 连接成功..."%(add[0]))
print(con.decode("utf-8"))
if con.decode("utf-8") == "break":
break
sends = input(">>>")
# 第一个参数是要发送的信息
# 第二个参数是接收方的ip和端口号
sock.sendto(sends.encode("utf-8"),("127.0.0.1",8011))
if sends == "break":
break
sock.close()
#客户
import socket
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
sock.bind(("",8011))
while True:
sends = input(">>>>")
sock.sendto(sends.encode("utf-8"),("127.0.0.1",8010))
if sends == "break":
break
con,add = sock.recvfrom(512)
print(con.decode("utf-8"))
if con.decode("utf-8") == "break":
break
sock.close()
给飞Q发消息
#给飞Q好友发消息
import socket
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
# sock.bind(("",8010))
sends = "1_lbt4_10#32499#002481627512#0#0#0:1289671407:a:b:288:呵呵哒~~~"
for i in range(256):
ip = "192.168.13.%d"%(i)#自己局域网ip
print(ip)
sock.sendto(sends.encode("gbk"),(ip,2425))
sock.close()
用户聊天
#聊天室服务器
import tkinter
import socket
import threading
win = tkinter.Tk()
win.title("QQ聊天室")
win.geometry("500x500+200+100")
users = {}
# 接收客户端发送过来的消息
def run(ck,ca):
global user
# print("**********")
# 接收消息
userName = ck.recv(1024)
# 创建一个字典 key为客户端的用户名 value为socket对象
users[userName.decode("utf-8")] = ck
# print(users)
while True:
# 接收消息
rData = ck.recv(1024)
# 将消息进行编码
dataStr = rData.decode("utf-8")
# 将接收到的消息进行切分
infolist = dataStr.split(":")
# 将消息发送给指定的好友
users[infolist[0]].send((userName.decode("utf-8")+":"+infolist[1]+"\n").encode("utf-8"))
def starts():
ipStr = eip.get()
# 获取端口号
portStr = eport.get()
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("", int(portStr)))
server.listen(10)
printStr = "服务器已启动...\n"
text.insert(tkinter.INSERT, printStr)
while True:
ck, ca = server.accept()
# 启动一个线程来连接客户端
t = threading.Thread(target=run, args=(ck, ca))
t.start()
printStrs = "%s 连接成功...\n"%(ca[0])
text.insert(tkinter.INSERT,printStrs)
def startserver():
# 启动一个线程来启动服务端
s = threading.Thread(target=starts)
s.start()
labelIp = tkinter.Label(win,text = "ip")
labelPort = tkinter.Label(win,text = "port")
eip = tkinter.Variable()
eport = tkinter.Variable()
entryIp = tkinter.Entry(win,textvariable = eip)
entryPort = tkinter.Entry(win,textvariable = eport)
button = tkinter.Button(win,text = "启动",command = startserver)
text = tkinter.Text(win,width = 30,height = 10)
labelIp.grid(row = 0,column = 0)
entryIp.grid(row = 0,column = 1)
labelPort.grid(row = 1,column = 0)
entryPort.grid(row = 1,column = 1)
button.grid(row = 2,column = 1)
text.grid(row = 3,column = 0)
win.mainloop()
#聊天室客户端
#可以创建多个用户
import threading
import tkinter
import socket
win = tkinter.Tk()
win.title("QQ客户端")
win.geometry("500x500+200+100")
ck = None
def getInfo():
while True:
# 接收信息
data = ck.recv(1024)
text.insert(tkinter.INSERT,data.decode("utf-8"))
def sendMail():
# 获取好友名
friend = efriend.get()
# 获取要发送的消息
sendStr = esend.get()
# 进行拼接
sendStr = friend + ":" + sendStr
# 发送拼接后的消息
ck.send(sendStr.encode("utf-8"))
def connectServer():
global ck
# 获取用户名
userStr = euser.get()
# 获取ip
ipStr = eip.get()
# 获取端口号
portStr = eport.get()
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 连接指定的服务器
client.connect((ipStr,int(portStr)))
# 向服务器发送消息
client.send(userStr.encode("utf-8"))
ck = client
# 等待接收消息
t = threading.Thread(target=getInfo)
t.start()
labelUser = tkinter.Label(win,text = "userName")
euser = tkinter.Variable()
entryUser = tkinter.Entry(win,textvariable = euser)
labelUser.grid(row = 0,column = 0)
entryUser.grid(row = 0,column = 1)
labelIp = tkinter.Label(win,text = "ip")
eip = tkinter.Variable()
entryIp = tkinter.Entry(win,textvariable = eip)
labelIp.grid(row = 1,column = 0)
entryIp.grid(row = 1,column = 1)
labelPort = tkinter.Label(win,text = "port")
eport = tkinter.Variable()
entryPort = tkinter.Entry(win,textvariable = eport)
labelPort.grid(row = 2,column = 0)
entryPort.grid(row = 2,column = 1)
button1 = tkinter.Button(win,text = "登陆",command = connectServer)
button1.grid(row = 3,column = 1)
text = tkinter.Text(win,width = 30,height = 10)
text.grid(row = 4,column = 0)
esend = tkinter.Variable()
entrySend = tkinter.Entry(win,textvariable = esend)
entrySend.grid(row = 6,column = 0)
efriend = tkinter.Variable()
labelFriend = tkinter.Label(win,text = "好友")
entryFriend = tkinter.Entry(win,textvariable = efriend)
entryFriend.grid(row = 5,column = 0)
labelFriend.grid(row = 5,column = 1)
button2 = tkinter.Button(win,text = "发送",command = sendMail)
button2.grid(row = 6,column = 1)
win.mainloop()
验证短信的发送
#接口类型:互亿无线触发短信接口,支持发送验证码短信、订单通知短信等。
#账户注册:请通过该地址开通账户http://sms.ihuyi.com/register.html
#注意事项:
#(1)调试期间,请用默认的模板进行测试,默认模板详见接口文档;
#(2)请使用APIID(查看APIID请登录用户中心->验证码短信->产品总览->APIID)及 APIkey来调用接口;
#(3)该代码仅供接入互亿无线短信接口参考使用,客户可根据实际需要自行编写;
#!/usr/local/bin/python
#-*- coding:utf-8 -*-
import http.client
import urllib
import time
host = "106.ihuyi.com"
sms_send_uri = "/webservice/sms.php?method=Submit"
#用户名是登录用户中心->验证码短信->产品总览->APIID
account = "C1818****"
#密码 查看密码请登录用户中心->验证码短信->产品总览->APIKEY
password = "7ce375e0021eabad7631fd90595c25b1"
def send_sms(text, mobile):
params = urllib.parse.urlencode({'account': account, 'password' : password, 'content': text, 'mobile':mobile,'format':'json' })
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
conn = http.client.HTTPConnection(host, port=80, timeout=30)
conn.request("POST", sms_send_uri, params, headers)
response = conn.getresponse()
response_str = response.read()
conn.close()
return response_str
if __name__ == '__main__':
mobile = "133********"
text = "您的验证码是:741741。请不要把验证码泄露给其他人。"
while True:
print(send_sms(text, mobile))
time.sleep(1)