• python线程与进程手记



    ------------------------------线程---------------------------
    #线程应用的第一种方式:thread模块是比较底层的模块
    #import thread:引用的模块
    #thread.start_new_thread(defName,()):线程的创建
    #thread.exit_thread():线程的结束


    #线程应用的第二种方式:threading模块是对thread做了一些包装,可以更方便被引用
    #import threading:引用的模块
    #myThread=threading.Thread(target=defName,args=('Alice',)):线程的创建
    #myThread.start():线程开始执行
    #num=len(threading.enumerate):线程数量的查看

    #线程应用的第三种方式:创建一个线程类,继承基类:threading.Thread 。重写def run(self):方法。需要运行的内容,写在run方法里面。
    #class MyThread(threading.Thread):创建类的对象
    #可以进行重构函数的对应扩展:def __init__(self,name,time):threading.Thread.__init__(self,name='对应的线程名字')
    #myThread=MyThread():创建对象
    #myThread.start():线程开始执行

    ------------------------------线程同步之互斥锁---------------------------
    #线程同步之互斥锁
    #互斥锁同步:线程同步能够保证多个线程安全访问竞争资源,最简单的同步机制是引用互斥锁。互斥锁为资源引入一个状态:锁定/非锁定。某个线程要更改共享数据时,先将其锁定,此时资源的状态为“锁定”,其他线程不能更改;直到该线程释放资源,将资源的状态变成“非锁定”,其他的线程才能再次锁定该资源。

    #mutex=threading.Lock():创建互斥锁
    #if mutex.acquire([blocking]):互斥锁锁定状态,返回值不为0表示上锁成功
    # 锁定方法acquire可以有一个blocking参数。如果设定blocking为True,则当前线程会堵塞,直到获取到这个锁为止(如果没有指定,那么默认为True);如果设定blocking为False,则当前线程不会堵塞
    #mutex.release():互斥锁释放状态


    ------------------------------线程同步至可重入锁---------------------------
    #线程同步之可重入锁
    #RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次acquire。直到一个线程所有的acquire都被release,其他的线程才能获得资源:
    #mutex=threading.RLock():创建可重入锁
    #mutex.acquire():可重入锁锁定状态
    #mutex.release():可重入锁释放状态

    ------------------------------线程同步之条件变量---------------------------
    #线程同步之条件变量
    #Python提供的Condition对象提供了对复杂线程同步问题的支持。Condition被称为条件变量,除了提供与Lock类似的acquire和release方法外,还提供了wait和notify方法。线程首先acquire一个条件变量,然后判断一些条件。如果条件不满足则wait;如果条件满足,进行一些处理改变条件后,通过notify方法通知其他线程,其他处于wait状态的线程接到通知后会重新判断条件。不断的重复这一过程,从而解决复杂的同步问题。

    #Condition对象维护了一个锁(Lock/RLock)和一个waiting池。线程通过acquire获得Condition对象,当调用wait方法时,线程会释放Condition内部的锁并进入blocked状态,同时在waiting池中记录这个线程。当调用notify方法时,Condition对象会从waiting池中挑选一个线程,通知其调用acquire方法尝试取到锁。

    #Condition对象的构造函数可以接受一个Lock/RLock对象作为参数,如果没有指定,则Condition对象会在内部自行创建一个RLock。

    #除了notify方法外,Condition对象还提供了notifyAll方法,可以通知waiting池中的所有线程尝试acquire内部锁。由于上述机制,处于waiting状态的线程只能通过notify方法唤醒,所以notifyAll的作用在于防止有线程永远处于沉默状态。

    #con=threading.Condition():创建条件变量
    #con.acquire():条件变量锁定状态
    #con.wait():线程释放Condition内部的锁并进入blocked状态,同时在waiting池中记录这个线程
    #con.notify():Condition对象会从waiting池中挑选一个线程,通知其调用acquire方法尝试取到锁
    #con.notifyAll():唤醒所有处于waiting池中的所有线程,防止有线程永远处于沉默状态
    #con.release():条件变量释放状态


    ------------------------------线程同步之队列---------------------------
    #from Queue import Queue:进行对应的队列包的引用
    #queue=Queue():队列的创建
    #queue.qsize():获取队列中内容的数量
    #queue.put(内容):向队列中添加对应的数据信息
    #queue.set():从队列中取出对应的数据
    #queue.empty():查看当前队列内容是否为空

     1 #引入对应的包
     2 import threading
     3 
     4 from Queue import Queue
     5 
     6 from time import sleep
     7 
     8 #线程生产者
     9 class Producer(threading.Thread):
    10     #重写run方法
    11     def run(self):
    12         global g_queue
    13 
    14         while True:
    15             if con.acquire():
    16                 #判断是否停止生产,获取队列中的数量
    17                 if g_queue.qsize() < 20:
    18 
    19                     #每次生产5个产品
    20                     for i in range(5):
    21                         g_queue.put("产品")
    22 
    23                     print("生产出5个产品,产品总量:%d"%g_queue.qsize())
    24                 else:
    25                     con.wait()
    26                     print("停止生产")
    27 
    28                 con.release()
    29             sleep(1)
    30 
    31 
    32 #线程消费者
    33 class Consumer(threading.Thread):
    34     #重写run方法
    35     def run(self):
    36         global g_queue
    37 
    38         while True:
    39             if con.acquire():
    40                 #判断是否停止消费
    41                 if g_queue.qsize()>5:
    42                     #进行消费
    43                     for i in range(3):
    44                         g_queue.get()
    45 
    46                     print("消费3 总数:%d"%g_queue.qsize())
    47 
    48                     if g_queue.qsize()<20:
    49                         con.notify()
    50                 con.release()
    51             sleep(1)
    52 
    53 #全局变量
    54 con=threading.Condition()
    55 #g_num=600
    56 #创建一个队列
    57 g_queue=Queue()
    58 
    59 
    60 #main函数
    61 def main():
    62     pro=Producer()
    63     pro.start()
    64     con=Consumer()
    65     con.start()
    66 
    67 #程序入口
    68 if __name__ == '__main__':
    69     main()
    线程队列实现生产者消费者

    ------------------------------线程间通信---------------------------

    threading.Event可以使一个线程等待其他线程的通知。其内置了一个标志,初始值为False。线程通过wait()方法进入等待状态,直到另一个线程调用set()方法将内置标志设置为True时,Event通知所有等待状态的线程恢复运行。还可以通过isSet()方法查询Envent对象内置状态的当前值。

    #event=threading.Event():进行对应Envent对象的创建
    #self.threadEvent=event :重构对应threading.Thread基类中的__init__的方法。
    #self.threadEvent.wait():使线程进入等待状态
    #event.set():启动waiting池中等待的线程


    ------------------------------线程的合并和后台线程---------------------------
    python的Thread类中还提供了join()方法,使得一个线程可以等待另一个线程执行结束后再继续运行。这个方法还可以设定一个timeout参数,避免无休止的等待。因为两个线程顺序完成,看起来象一个线程,所以称为线程的合并。
    默认情况下,主线程在退出时会等待所有子线程的结束。如果希望主线程不等待子线程,而是在退出时自动结束所有的子线程,就需要设置子线程为后台线程(daemon)。方法是通过调用线程类的setDaemon()方法。

    #myThread.setDaemon(True):将该线程转为后台线程


    ------------------------------ThreadLocal---------------------------
    global_dict={}
    global_dict[threading.current_thread()]


    ------------------------------多进程---------------------------
    在Unix/Linux操作系统中,提供了一个fork()系统函数,它非常特殊。

    普通的函数调用,调用一次,返回一次,但是fork()调用一次,返回两次,因为操作系统自动把当前进程(称为父进程)复制了一份(称为子进程),然后,分别在父进程和子进程内返回。

    子进程永远返回0,而父进程返回子进程的ID。

    这样做的理由是,一个父进程可以fork出很多子进程,所以,父进程要记下每个子进程的ID,而子进程只需要调用getppid()就可以拿到父进程的ID。

    #import os :引用对应的进程包

    #pid=os.fork():程序执行到os.fork()时,操作系统会创建一个新的进程(子进程),然后复制父进程的所有信息到子进程中,然后父进程和子进程都会从fork()函数中得到一个返回值,其进程中这个值一定是0,而父进程中是子进程的 id号

    #os.getpid():获取当前进程的pid
    #os.getppid():获取父进程的pid

    ------------------------------multiprocessing模块---------------------------
    #from multiprocessing import Process:multiprocessing模块提供了一个Process类来代表一个进程对象。
    #p=Process(target=run_proc,args=('test',)):创建对应的进程对象
    #p.start():进程的启动
    #p.join():multiprocessing模块提供了一个Process类来代表一个进程对象,下面的例子演示了启动一个子进程并等待其结束
    #multiprocessing.cpu_count():查看对应的cpu核数
    #pipe=multiprocessing.Pipe():创建一个管道,管道两个端口调用分别为pipe[0],pipe[1]
    #pipe[0].send(i):为管道一侧进行内容的添加操作
    #pipe[0].recv():获取管道一侧的内容信息

     1 #coding=utf-8
     2 
     3 #引用对应的包
     4 from socket import *
     5 
     6 from multiprocessing import Process
     7 
     8 import sys
     9 
    10 #进程函数:为客户提供tcp服务
    11 def tcpClient(newSocket,destAddr): 
    12     print("客户端(%s)以上线"%str(destAddr))
    13     while True:
    14         #数据的接受
    15         recvData=newSocket.recv(1024)
    16         #模拟echo将数据回发服务器
    17         newSocket.send(recvData)
    18         
    19         #如果接收的数据长度为0,进行客户端的关闭操作
    20         if len(recvData) <= 0:
    21             print("------客户端(%s)已经下线-------"%str(destAddr))
    22             
    23             newSocket.close()
    24             break        
    25         print ("客户端(%s)传递过的数据为:%s"%(str(destAddr),recvData))
    26 
    27 
    28 #函数:main
    29 def main():
    30     #创建Tcp套接字
    31     socTcpSer=socket(AF_INET,SOCK_STREAM)
    32 
    33     socTcpSer.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
    34 
    35     #创建ip和端口进行绑定
    36     local=("",int(sys.argv[1]))
    37     socTcpSer.bind(local)
    38 
    39     #开启监听程序
    40     socTcpSer.listen(5)
    41 
    42     print('---------等待客户端上线---------')
    43     
    44     #进行服务的开启,并循环为客户进行服务
    45     while True:
    46 
    47         #接受客户端响应信息
    48         newSocket,destAddr=socTcpSer.accept()
    49         
    50         #创建子进程
    51         pClient=Process(target=tcpClient,args=(newSocket,destAddr,))
    52         
    53         #子进程开始
    54         pClient.start()
    55 
    56     socTcpSer.close()
    57 
    58 
    59 #程序入口
    60 if __name__=='__main__':
    61     main()
    62 
    63 多进程实现tcp服务
    多进程模拟tcp服务
  • 相关阅读:
    WCF中神秘的“8731"端口和“Design_Time_Addresses”
    wcf分布式构架集群案例解决方案
    asp.net odjectdatasource的用法
    ClientBase<T>中对ChannelFactory<T>的缓存机制
    asp.net datatable中行的复制
    c#连接各种数据库的方法
    wcf系列学习5天速成——事务的使用
    Atitit 软件设计中的各种图纸 uml 之道 1. 常见设计成果与图纸 2 1.1. 总图 2 1.2. ui原型图与html 2 1.3. 业务逻辑 伪代码 各种uml图 2 1.4. 总体
    Atitit 综合原则 软件与项目开发中的理念信念 目录 1.1. 建议组合使用扬长避短 1 1.2. 常见数据库 mysql oracle mssql mongodb postgre sqlit
    Atitit it理论不可能三角“:“安全方便廉价 目录 1. 不可能三角 1 2. 三元悖论 1 2.1. 培恩洛兹三角形 2 2.2. 彭罗斯三角(Penrose triangle) 2 2.
  • 原文地址:https://www.cnblogs.com/qingtianyu2015/p/5831068.html
Copyright © 2020-2023  润新知