python进程和线程

1.多进程

针对unix/linux操作系统会提供一个fork()系统调用,其调用一次,返回两次,因为操作系统自动把当前文件复制了一份,称为父进程和子进程

子进程永远返回0,而父进程返回子进程的ID,这样一个父进程可以fork出很多子进程,so父进程要记下每个子进程的ID,而子进程通过调用getppid()拿到父进程的ID

python中的os模块封装了常见的系统调用,其中包括fork

1)Mutiprocessing

跨平台版本的多进程模块,提供process类来代表一个进程对象

from multiprocessing import Process
import os
#子进程要执行的代码
def run_proc(name):
    print("run child process %s(%s)..."%(name,os.getpgid()))
if _name_== '_main_':
    print(("parent process %s"%os.getpgid()))
    p = Process(target=run_proc,args=("test",))
    print("child process will start")
    p.start()
    p.join()
    print("child will end")

2)pool

如果启动大量的子进程,可以用进程池的方式批量创建子进程

from multiprocessing import Process
import os,time,random
#子进程要执行的代码
def long_time_task(name):
    print("run child process %s(%s)..."%(name,os.getpgid()))
    start=time.time()
    time.sleep(random.random()*3)
    end=time.time()
    print("Task %s runs %0.2f seconds"%(name,(end-start)))
if _name_=='_main_':
    print(("parent process %s"%os.getpgid()))
    p = pool(4)
    for i in range(5):
        p.apply_async(long_time_task,args=(i,))
    print("waiting for all subprocesses done")
    p.start()
    p.join()
    print("All subprocesses done")'

3)子进程

subprocess模块可以方便的启动一个子进程

import subprocess
print("$ nslookup www.python.org")
r = subprocess.call(["nslookup","www.python.org"])
print("Exit code",r)

如果子进程还需要输入,则可以通过communicate()方法输入

import subprocess
print("$ nslookup")
p = subprocess.Popen(["nslookup"],stdin = subprocess.PIPE,stdout = subprocess.PIPE,stderr = subprocess.PIPE)
output,err = p.communicate(b'set q=mx\npython.org\nexit\n')
print(output.decode("utf-8"))
print("Exit code",p.returncode)

4)进程间通信

process之间需要通信,python的multiprocessing模块包装了底层的机制,提供了Queue\Pipes等多种方式来交换数据

以Queue为例,一个往Queue里面写入数据,一个从Queue里面读数据

def read(q):
    print("process to read:%s"%os.getpgid())
    while True:
        value = q.get(True)
        print("get %s from queue"%value)
if _name_ = "main_":
    q =Queue()
    pw =Process(target = write,args=(q,))
    pr = Process(target=read,args=(q,))
    pw.start()
    pr.start()
    pw.join()
    pr.terminate()

2.多线程

python提供了连个模块,一个是_thread和threading,前者是低级模块,后者是高级模块,高级模块对低级模块进行了封装,绝大多数我们使用高级模块

import time,threading
def loop():
    print("thread in running"%threading.current_thread().name)
    n = 0
    while n < 5:
        n = n+1
        print("thread %s >>> %s"%threading.current_thread().name,n)
        time.sleep(1)
    print("thread %s  ended"%threading.current_thread().name)
print("thread %s is runing"%threading.current_thread().name)
t = threading.Thread(target=loop,name = "Looptaread")
t.start()
t.join()
print("thread %s  ended"%threading.current_thread().name)

1)lock

多线程和多进程的最大区别在于,多进程中每一个变量都有各自的备份,备份在每一个进程中,互不影响,而在多线程中,所有变量由所有线程共享,线程之间共享的问题在于多个线程同时更改一个变量,我们用锁实现,即threading_lock

import threading
balance = 0
lock = threading.Lock()
def run_thread(n):
    for i in range(1000):
        #先获取锁
    lock.acquire()
    try:
        change_it(n)
    finally:
        #释放锁
        lock.release()

 3.ThreadLocal

作为全局变量,但每个线程都只能读写自己线程的独立副本,互不干扰,解决了参数在一个线程中各个函数之间相互传递的问题。

import threading
local_school = threading.local()
def process_student():
    std = local_school.student
    print("hello,%s(in %s)"%(std,threading.current_thread().name))
def process_thread(name):
    local_school.student= name
    process_student()
t1 = threading.Thread(target=process_thread,args=("alice"),name="thread_A")
t2 = threading.Thread(target=process_thread,args=("bob"),name="thread_B")
t1.start()
t2.start()
t1.join()
t2.join()

4.进程vs.线程

多进程的最大优点在于稳定性高,缺点在于创建进程的代价大

多线程通常比进程快一点,致命缺点在于任何一个进程崩溃可能直接造成整个进程坏掉,因为所有进程共享进程内存

5.分布式进程

6.正则表达式

\d:匹配一个数字

\w:匹配一个字母或数字

.:可以匹配任意字符

*:匹配任意个字符

+:匹配至少一个字符

?:表示匹配一个或者0个字符

{n}表示n个字符,用{你,m}表示n-m个字符

对于特殊字符进行转义:\

[]:表示更加精确的匹配

|:表示或

^:表示行的开头

^\d:表示以数字开头

$:表示结束

\d$:表示必须以数字结束

re模块,包含所有的正则表达式

以及使用match模块判断是否匹配成功

切分字符串:

分组:用()表示提取的分组,用Match()对象上的group()方法提取子串

贪婪匹配:匹配尽可能多的字符

 

posted @ 2019-11-27 09:02  行之!  阅读(194)  评论(0编辑  收藏  举报