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 python.org exit ') print(output.decode("utf-8")) print("Exit code",p.returncode)
4)进程间通信
process之间需要通信,python的multiprocessing模块包装了底层的机制,提供了QueuePipes等多种方式来交换数据
以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()方法提取子串
贪婪匹配:匹配尽可能多的字符