python-多进程(101)

import os

print('starting...')
os.fork()   #生成子进程,后续代码在父子进程中运行
print('Hello Word!')

#可以根据fork()的返回值判断是父进程还是子进程
# [root@zhuji pyrhon百例]# python3 101多进程.py
# starting...
# Hello Word!
# Hello Word!   #fork()后会出现子进程,父子进程都会打印Hello Word!,所以会打印两行Hello Word!





import os

print('starting...')
pid = os.fork() #返回值是一个数值,对于父进程,返回值是子进程的PID,子进程是0
if pid:     #如果pid不为0,则执行父进程,为0则执行子进程
    print('In parent')  #父进程执行的代码
else:
    print('In Child')   #子进程执行的代码
print('Done...')    #父子进程都会执行的代码

# [root@zhuji pyrhon百例]# python3 101多进程.py
# starting...
# In parent
# Done...
# In Child
# Done...




# 多进程编程时,要明确父子进程的工作。如:父进程只用于fork子进程;
# 子进程做具体的工作,如果在循环结构中,做完后要退出,否则子进程还会再产生子进程、孙进程……,系统会崩溃。
import os

for i in range(5):
    pid = os.fork() #父进程执行的工作是生成子进程,子进程再执行代码
    if not pid:     #not pid,为真即pid为0,执行下面的代码,也就是子进程执行代码
        print('hello')
        #exit()  #子进程执行完以后关闭


# 加上了,exit(),若不加则会打印很多的hello
# [root@zhuji pyrhon百例]# python3 101多进程.py
# hello
# hello
# hello
# hello
# hello





#多进程的ping

#没有多进程,ping一个网段的IP地址往往要花费几十分钟;使用多进程,几秒钟解决。

import subprocess
import os

def ping(host):
    rc = subprocess.call(   #执行shell命令
        'ping -c2 %s &> /dev/null' % host,
        shell=True      #固定格式
    )
    if rc:
        print('%s:down' % host)
    else:
        print('%s:up' % host)

if __name__ == '__main__':
    ips = ('192.168.1.%s' % i for i in range(1,255))
    for ip in ips:
        pid = os.fork()
        if not pid:
            ping(ip)
            exit()





#多进程的效率
# 没有多进程,即使CPU有多个核心,程序只是运行在一个核心上,无法利用多进程提升效率。
# 5000万次加法,如果需要2.5秒,调用两次共花费5秒。
import time
def calc():
    result = 0
    for i in range(1,50000001):
        result += i
    print(result)

if __name__ == '__main__':
    start = time.time()
    calc()
    calc()
    end = time.time()
    print(end - start)

# [root@room9pc01 untitled]# python3 101多进程.py
# 1250000025000000
# 1250000025000000
# 3.690995693206787


#通过多进程,程序运行在多个核心上,
# 同样的调用两次5000万次加法运算,时间仅为一半
import time
import os

def calc():
    result = 0
    for i in range(1,50000001):
        result += i
    print(result)

if __name__ == '__main__':
    start = time.time()
    for i in range(2):
        pid = os.fork()
        if not pid:
            calc()
            exit()
    os.waitpid(-1,0)    #挂起父进程,直到子进程结束才继续向下执行
    os.waitpid(-1,0)    #每个waitpid只能处理一个僵尸进程,两个子进程需要调用两次
    end = time.time()
    print(end - start)

# [root@room9pc01 untitled]# python3 101多进程.py
# 1250000025000000
# 1250000025000000
# 1.9002265930175781





#僵尸进程
#多进程编程要注意僵尸进程。子进程没有可执行代码后将变成僵尸进程,
# 如果父进程一直运行,又没有处理僵尸进程的代码,僵尸进程也将一直存在,
# 消耗资源。僵尸进程无法通过kill命令杀掉。
import os
import time

pid = os.fork()
if pid:
    print('In parent. sleeping...')
    time.sleep(60)
    print('parent done.')
else:
    print('in child. sleeping...')
    time.sleep(10)
    print('child done') #10秒后,子进程变成了僵尸进程

#watch -n1 ps a     #每隔1秒,执行一次ps a ,当子进程为僵尸进程时显示为z






#解决僵尸进程问题
#os.waitpid()的第2个参数,0表示挂起父进程,1表示不挂起父进程。
import os
import time

pid = os.fork()
if pid:
    print('In parent. sleeping...')
    print(os.waitpid(-1,1)) #无僵尸u进程可以处理,返回0、
    time.sleep(20)
    print(os.waitpid(-1,1)) #处理僵尸进程,返回子进程pid
    time.sleep(60)
    print('parent done.')
else:
    print('in child. sleeping...')
    time.sleep(10)
    print('child done')





#基于多进程的时间消息服务器
# 1、支持多客户端同时访问
# 2、客户端向服务器发送消息后,服务器把消息加上时间发回客户端
# 3、每个客户端断开后会产生僵尸进程,新客户端连接时销毁所有的僵尸进程
import socket
import os
from time import strftime

class TcpTimeServer:
    def __init__(self,host='',port=12345):
        self.addr = (host,port)
        self.serv = socket.socket()
        self.serv.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
        self.serv.bind(self.addr)
        self.serv.listen(1)

    def chat(self,c_sock):
        while True:
            data = c_sock.recv(1024)
            if data.strip() == b'quit':
                break
            data = '[%s] %s' % (strftime('%H:%M:%S'),data.decode('utf8'))
            c_sock.send(data.encode('utf8'))
        c_sock.close()

    def mainloop(self):
        while True:
            cli_sock,cli_addr = self.serv.accept()
            pid = os.fork()
            if pid:
                cli_sock.close()
                while True:
                    result = os.waitpid(-1,1)[0]
                    if result == 0:
                        break
            else:
                self.serv.close()
                self.chat(cli_sock)
                exit()
        self.serv.close()

if __name__ == '__main__':
    s = TcpTimeServer()
    s.mainloop()





#基于多线程的ping
# 多线程与多进程类似,但是每个线程没有自己的资源空间,它们共用进程的资源。
# 多线程没有僵尸进程的问题。
import subprocess
import threading

def ping(host):
    rc = subprocess.call(
        'ping -c2 %s &> /dev/null' % host,
        shell=True
    )
    if rc:
        print('%s: down' % host)
    else:
        print('%s: up' % host)

if __name__ == '__main__':
    ips = ['192.168.4.%s' % i for i in range(1,255)]
    for ip in ips:
        t = threading.Thread(target=ping,args=(ip,))
        t.start()






#多线程的效率
#python的多线程有一个GIL(全局解释器锁),使得多个线程,
# 某一时刻只有一个线程发送给CPU处理。所以多线程不适用计算密集型应用,
# 更适合IO密集型应用。
#以下两次计算5000万次加法运算和不用多线程相比,没有效率的提升。
# 因为CPU有上下文切换,甚至可能多线程更慢
import time
import threading

def calc():
    result = 0
    for i in range(1,50000001):
        result += i
    print(result)

if __name__ == '__main__':
    start = time.time()
    t1 = threading.Thread(target=calc)
    t1.start()
    t2 = threading.Thread(target=calc)
    t2.start()
    t1.join()   #挂起主进程,当t1线程执行完后才继续向下执行
    t2.join()
    end = time.time()
    print(end - start)

# [root@room9pc01 untitled]# python3 101多进程.py
# 1250000025000000
# 1250000025000000
# 3.826401948928833





#基于多线程的时间消息服务器
import socket
import threading
from time import strftime

class TcpTimeServer:
    def __init__(self,host='',port=12345):
        self.addr = (host,port)
        self.serv = socket.socket()
        self.serv.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
        self.serv.bind(self.addr)
        self.serv.listen(1)

    def chat(self,c_sock):
        while True:
            data = c_sock.recv(1024)
            if data.strip() == b'quit':
                break
            data = '[%s] %s' % (strftime('%H:%M:%S'),data.decode('utf8'))
            c_sock.send(data.encode('utf8'))
        c_sock.close()

    def mainloop(self):
        while True:
            cli_sock,cli_addr = self.serv.accept()
            t = threading.Thread(target=self.chat,args=(cli_sock,))
            t.start()
        self.serv.close()

if __name__ == '__main__':
    s = TcpTimeServer()
    s.mainloop()




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值