python&&ftp上传和多线程开发&&学习笔记

系统 1805 0

python&&ftp上传和多线程开发&&学习笔记

    • FTP文件上传
      • FTP文件上传示例
      • 堡垒机程序示例
      • SSH密码账号远程登录服务器示例
      • SSH密钥远程登录服务器示例
      • SSH上传和下载文件
    • 线程与进程简介
      • 应用程序、进程、线程的关系
      • 简单创建线程示例1
      • 多线程开发的方法
      • 多线程之方法应用示例
      • 多线程之自定义线程类示例
      • 多线程之生产者与消费者模型示例一
      • 函数式编程实现生产者与消费者模型
      • 多线程开发之线程锁
      • 多线程开发之event事件

FTP文件上传

FTP文件上传示例

示例框架
python&&ftp上传和多线程开发&&学习笔记_第1张图片
server.py(运行异常,仅参考)

            
              
                #!/usr/bin/env python
              
              
                #coding:utf-8
              
              
                #导入模块socketserver,利用多线程实现多个用户同时上传下载文件
              
              
                import
              
               socketserver

              
                import
              
               os 

              
                from
              
               test
              
                .
              
              test_decimal 
              
                import
              
              
                file
              
              
                class
              
              
                myServer
              
              
                (
              
              socketserver
              
                .
              
              BaseRequestHandler
              
                )
              
              
                :
              
              
                def
              
              
                handle
              
              
                (
              
              self
              
                )
              
              
                :
              
              
                #定义文件存放根路径
              
              
        basePath 
              
                =
              
              
                'D:/backupAll\eclipseRoot\temp'
              
              
        clientObj 
              
                =
              
               self
              
                .
              
              request
        
              
                print
              
              
                (
              
              
                '连接成功...'
              
              
                )
              
              
                while
              
              
                True
              
              
                :
              
              
                #获取发送头信息
              
              
            preData 
              
                =
              
               clientObj
              
                .
              
              recv
              
                (
              
              
                1024
              
              
                )
              
              
            preDataToStr 
              
                =
              
              
                str
              
              
                (
              
              preData
              
                ,
              
               encoding 
              
                =
              
              
                "utf8"
              
              
                )
              
              
                print
              
              
                (
              
              preDataToStr
              
                )
              
              
            cmd
              
                ,
              
              fileName
              
                ,
              
              fileSize 
              
                =
              
               preDataToStr
              
                .
              
              split
              
                (
              
              
                '|'
              
              
                )
              
              
            recvSize 
              
                =
              
              
                0
              
              
                #拼接路径
              
              
            fileDir 
              
                =
              
               os
              
                .
              
              path
              
                .
              
              join
              
                (
              
              basePath
              
                ,
              
              fileName
              
                )
              
              
            f 
              
                =
              
              
                file
              
              
                (
              
              fileDir
              
                ,
              
              
                'wb'
              
              
                )
              
              
            Flag 
              
                =
              
              
                True
              
              
                while
              
               Flag
              
                :
              
              
                if
              
              
                int
              
              
                (
              
              fileSize
              
                )
              
              
                >
              
               recvSize
              
                :
              
              
                    data 
              
                =
              
               clientObj
              
                .
              
              recv
              
                (
              
              
                1024
              
              
                )
              
              
                    recvSize 
              
                +=
              
              
                len
              
              
                (
              
              data
              
                )
              
              
                else
              
              
                :
              
              
                    recvSize 
              
                =
              
              
                0
              
              
                    FLag 
              
                =
              
              
                False
              
              
                #数据由内存写入硬盘
              
              
                f
              
                .
              
              write
              
                (
              
              data
              
                )
              
              
                print
              
              
                (
              
              
                '上传完毕'
              
              
                )
              
              
                
instance 
              
                =
              
               socketserver
              
                .
              
              ThreadingTCPServer
              
                (
              
              
                (
              
              
                '127.0.0.1'
              
              
                ,
              
              
                9999
              
              
                )
              
              
                ,
              
              myServer
              
                )
              
              
instance
              
                .
              
              serve_forever
              
                (
              
              
                )
              
            
          

client.py

            
              
                #!/usr/bin/env python
              
              
                #coding:utf-8
              
              
                #由于文件的发送传输需要经过缓冲区,缓冲区大小固定(一般为8096),所以在实现对文件的发送传输时需要将文件切割成固定大小发送。
              
              
                #导入模块
              
              
                from
              
               pip
              
                .
              
              _vendor
              
                .
              
              distlib
              
                .
              
              compat 
              
                import
              
              
                raw_input
              
              
                from
              
               test
              
                .
              
              test_decimal 
              
                import
              
              
                file
              
              
                import
              
                socket

              
                import
              
               os




              
                #定义变量
              
              
ipAddress 
              
                =
              
              
                (
              
              
                "127.0.0.1"
              
              
                ,
              
              
                9999
              
              
                )
              
              
socketObj 
              
                =
              
               socket
              
                .
              
              socket
              
                (
              
              
                )
              
              
socketObj
              
                .
              
              connect
              
                (
              
              ipAddress
              
                )
              
              
                #创造重复循环
              
              
                while
              
              
                True
              
              
                :
              
              
                #接收"文件操作命令(上传(put)、下载(get))|文件路径"
              
              
                input
              
              
                =
              
              
                raw_input
              
              
                (
              
              
                'path:'
              
              
                )
              
              
                #分离存放文件操作命令(上传、下载)和文件路径
              
              
    cmd
              
                ,
              
              path 
              
                =
              
              
                input
              
              
                .
              
              split
              
                (
              
              
                '|'
              
              
                )
              
              
                #定义文件名称
              
              
    fileName 
              
                =
              
               os
              
                .
              
              path
              
                .
              
              basename
              
                (
              
              path
              
                )
              
              
                #定义文件大小
              
              
    fileSize 
              
                =
              
               os
              
                .
              
              stat
              
                (
              
              path
              
                )
              
              
                .
              
              st_size
    strOne 
              
                =
              
               cmd
              
                +
              
              
                "|"
              
              
                +
              
              fileName
              
                +
              
              
                "|"
              
              
                +
              
              
                str
              
              
                (
              
              fileSize
              
                )
              
              
    strToBit 
              
                =
              
               strOne
              
                .
              
              encode
              
                (
              
              encoding
              
                =
              
              
                'utf_8'
              
              
                ,
              
               errors
              
                =
              
              
                'strict'
              
              
                )
              
              
                #发送消息到
              
              
    socketObj
              
                .
              
              send
              
                (
              
              strToBit
              
                )
              
              
                #文件发送进度
              
              
    sendSize 
              
                =
              
              
                0
              
              
    f 
              
                =
              
              
                file
              
              
                (
              
              path
              
                ,
              
              
                'rb'
              
              
                )
              
              
    Flag 
              
                =
              
              
                True
              
              
                while
              
               Flag
              
                :
              
              
                #如果文件发送剩余大小不足1024,则读取发送剩余大小数据并结束重复循环
              
              
                if
              
               sendSize 
              
                +
              
              
                1024
              
              
                >
              
               fileSize
              
                :
              
              
            data 
              
                =
              
               f
              
                .
              
              read
              
                (
              
              fileSize 
              
                -
              
               sendSize
              
                )
              
              
            Flag 
              
                =
              
              
                False
              
              
                #否则,读取发送固定大小文件数据并记录w文件发送进度
              
              
                else
              
              
                :
              
              
            data 
              
                =
              
               f
              
                .
              
              read
              
                (
              
              
                1024
              
              
                )
              
              
            sendSize 
              
                +=
              
              
                1024
              
              
        f
              
                .
              
              close
              
                (
              
              
                )
              
              
socketObj
              
                .
              
              close
              
                (
              
              
                )
              
            
          

堡垒机程序示例

需求 :记录用户在服务器的所有操作
1.需要一台主机当做堡垒机
2.所有用户只能登陆堡垒机
3.登陆堡垒机后,可以远程服务器进行操作
4.记录用户的所有操作
过程 :登陆堡垒机》选择服务器》操作服务器:记录操作
实现过程
1.创建堡垒机用户

            
            
          

2.用户登陆堡垒机后

SSH密码账号远程登录服务器示例

sshDemo.py

            
              
                #!/usr/bin/env python
              
              
                #coding:utf-8
              
              
                #导入模块
              
              
                import
              
               paramiko

              
                #实例化
              
              
ssh 
              
                =
              
               paramiko
              
                .
              
              SSHClient
              
                (
              
              
                )
              
              
                #应对第一个远程登录的用户签名(yes or no),该行代码默认填写yes。
              
              
ssh
              
                .
              
              set_missing_host_key_policy
              
                (
              
              paramiko
              
                .
              
              AutoAddPolicy
              
                (
              
              
                )
              
              
                )
              
              
                #远程登录账号,密码
              
              
ssh
              
                .
              
              connect
              
                (
              
              
                '192.168.1.223'
              
              
                ,
              
              
                22
              
              
                ,
              
              
                'root'
              
              
                ,
              
              
                'yibotong'
              
              
                )
              
              
                #设置需要使用Linux命令并捕捉命令返回结果(输入,输出,错误)
              
              
stdin
              
                ,
              
              stdout
              
                ,
              
              stderr 
              
                =
              
               ssh
              
                .
              
              exec_command
              
                (
              
              
                'df'
              
              
                )
              
              
                #打印结果
              
              
                print
              
              
                (
              
              stdout
              
                .
              
              read
              
                (
              
              
                )
              
              
                )
              
              
ssh
              
                .
              
              close
              
                (
              
              
                )
              
              
                ;
              
            
          

SSH密钥远程登录服务器示例

服务器操作生成密钥操作

            
              
                #ssh命令产生密钥对
              
              
ssh-keygen -t rsa

              
                #将本地公钥复制到远程服务器内部(/root/.ssh/id_rsa.pub)
              
              
ssh-copy-id root@192.168.1.139

            
          

python密钥登录

            
              
                #!/usr/bin/env python
              
              
                #coding:utf-8
              
              
                #导入模块
              
              
                import
              
               paramiko

              
                #定义私钥文件位置
              
              
private_key_path 
              
                =
              
              
                '/home/auto/.ssh/id_rsa'
              
              
                #取出私钥
              
              
key 
              
                =
              
               paramiko
              
                .
              
              RSAKey
              
                .
              
              from_private_key_file
              
                (
              
              private_key_path
              
                )
              
              
                #实例化
              
              
ssh 
              
                =
              
               paramiko
              
                .
              
              SSHClient
              
                (
              
              
                )
              
              
                #应对第一个远程登录的用户签名(yes or no),该行代码默认填写yes。
              
              
ssh
              
                .
              
              set_missing_host_key_policy
              
                (
              
              paramiko
              
                .
              
              AutoAddPolicy
              
                (
              
              
                )
              
              
                )
              
              
                #远程登录账号
              
              
ssh
              
                .
              
              connect
              
                (
              
              
                '192.168.1.223'
              
              
                ,
              
              
                22
              
              
                ,
              
              username
              
                =
              
              
                'root'
              
              
                ,
              
              pkey
              
                =
              
              key
              
                )
              
              
                #设置需要使用Linux命令并捕捉命令返回结果(输入,输出,错误)
              
              
stdin
              
                ,
              
              stdout
              
                ,
              
              stderr 
              
                =
              
               ssh
              
                .
              
              exec_command
              
                (
              
              
                'df'
              
              
                )
              
              
                #打印结果
              
              
                print
              
              
                (
              
              stdout
              
                .
              
              read
              
                (
              
              
                )
              
              
                )
              
              
ssh
              
                .
              
              close
              
                (
              
              
                )
              
              
                ;
              
            
          

rsa公钥与私钥的区别
私钥是自己用的,用于解密;公钥用于加密。
rsa公钥与私钥工作原理
远程登录时,客户端使用tcp协议发送连接请求(欲连接ssh端口),远程服务器使用公钥随机加密一段数据发送到客户端,客户端使用本地私钥解密,解密完成后将数据发送到服务端,服务端对解密数据进行比对,若匹配成功,则公钥与私钥配对成功,即远程登录成功。

SSH上传和下载文件

参考:***cnblogs.com/wupeiqi/articles/4356675.html

            
            
          

线程与进程简介

应用程序、进程、线程的关系

一个应用程序里面可以有多个进程,一个进程里面可以有多个线程。
全局解释器锁
在程序运行过程中,同一时间,一个进程里面只能有一个线程通过全局解释器锁进入cpu执行。
多进程与多线程的选择
计算密集型程序需要消耗大量cpu资源,故选择多进程模式;IO密集型程序选择多线程模式。
进程的开销通常比线程昂贵,因为线程自动共享内存地址空间和文件描述符,这意味着,创建进程比创建线程会花费更多。
在执行一些sleep/read/write/recv/send等会导致阻塞的函数时,当前线程会主动放弃GIL,然后调用相应的系统API,完成后再重新申请GIL.因此,GIL也并不是导致python的多线程完全没用。在一些IO等待的场合,python的多线程还是发挥了作用,当然如果多线程都是用于CPU密集的代码,那多线程的执行效率明显会比单线程的低。

线程是共享内存的,线程由进程管理,所有线程共享主线程的内存空间;进程的内存空间是互相独立,没有交集的。

简单创建线程示例1

            
              
                #!/usr/bin/env python
              
              
                #coding:utf-8
              
              
                #导入threading模块下的Thread类
              
              
                from
              
               threading 
              
                import
              
               Thread

              
                #定义方法
              
              
                def
              
              
                funcOne
              
              
                (
              
              arg
              
                )
              
              
                :
              
              
                print
              
              
                (
              
              arg
              
                )
              
              
                print
              
              
                (
              
              
                'before start thread'
              
              
                )
              
              
                #实例化Thread类形成对象,相当于创建了一个线程.
              
              
                #使用target参数在定义的方法(函数)与线程之间建立联系
              
              
                #线程对象 = Thread(target=函数名,args(参数)=(1(仅需一个参数故此处写一),))
              
              
threadOne 
              
                =
              
               Thread
              
                (
              
              target
              
                =
              
              funcOne
              
                ,
              
              args
              
                =
              
              
                (
              
              
                1
              
              
                ,
              
              
                )
              
              
                )
              
              
                #1后面为什么加逗号?因为当遇到字典、列表、元组时,其与方法、函数在调用时操作类似,故容易因为区分错误而报错,后面加逗号,可以说明这是一个序列,以此作为区分。
              
              
                #在运行对象时,并不一定马上执行,按系统调度规则被轮训到时执行
              
              
threadOne
              
                .
              
              start
              
                (
              
              
                )
              
              
                print
              
              
                (
              
              
                'after start thread'
              
              
                )
              
            
          

多线程开发的方法

threading.Thread模块

  • start
  • getName()
  • setName():更改线程名称
  • isDaemon()
  • setDaemon()
  • join(timeout)
  • run

线程创建不宜过多也不宜过少,恰当最好。线程过少时,执行效率低;线程过多时会导致上下文切换频繁,造成大量资源浪费。

多线程之方法应用示例

            
              
                #!/usr/bin/env python
              
              
                #coding:utf-8
              
              
                #导入threading模块下的Thread类
              
              
                from
              
               threading 
              
                import
              
               Thread

              
                import
              
               time

              
                #定义方法
              
              
                def
              
              
                funcOne
              
              
                (
              
              arg
              
                )
              
              
                :
              
              
                print
              
              
                (
              
              arg
              
                )
              
              
                def
              
              
                funcTwo
              
              
                (
              
              arg
              
                ,
              
              v
              
                )
              
              
                :
              
              
                for
              
               item 
              
                in
              
              
                range
              
              
                (
              
              
                100
              
              
                )
              
              
                :
              
              
                print
              
              
                (
              
              item
              
                )
              
              
        time
              
                .
              
              sleep
              
                (
              
              
                1
              
              
                )
              
              
                print
              
              
                (
              
              
                'before start thread'
              
              
                )
              
              
                #实例化Thread类形成对象,相当于创建了一个线程.
              
              
                #使用target参数在定义的方法(函数)与线程之间建立联系
              
              
                #线程对象 = Thread(target=函数名,args=(参数1,))
              
              
threadOne 
              
                =
              
               Thread
              
                (
              
              target
              
                =
              
              funcOne
              
                ,
              
              args
              
                =
              
              
                (
              
              
                '参数1'
              
              
                ,
              
              
                )
              
              
                )
              
              
threadTwo 
              
                =
              
               Thread
              
                (
              
              target
              
                =
              
              funcTwo
              
                ,
              
              args
              
                =
              
              
                (
              
              
                '参数1'
              
              
                ,
              
              
                '参数2'
              
              
                )
              
              
                )
              
              
                #1后面为什么加逗号?因为当遇到字典、列表、元组时,其与方法、函数在调用时操作类似,故容易因为区分错误而报错,后面加逗号,可以说明这是一个序列,以此作为区分。
              
              
                #在程序运行时,当主线程已经执行结束,而子线程执行缓慢仍未结束时,主线程需要等待子线程执行结束才终止程序运行。
              
              
                #输出当前daemon状态,默认False
              
              
                print
              
              
                (
              
              threadTwo
              
                .
              
              isDaemon
              
                (
              
              
                )
              
              
                )
              
              
                #设置daemon状态,此时不再遍历100之内的数字。
              
              
                #通过设置daemon状态,可以让子线程随主线程的执行结束而结束,主线程不再等待子线程(threadOne和threadTwo)执行结束。
              
              
threadOne
              
                .
              
              setDaemon
              
                (
              
              
                True
              
              
                )
              
              
threadTwo
              
                .
              
              setDaemon
              
                (
              
              
                True
              
              
                )
              
              
                #在运行对象时,并不一定马上执行,按系统调度规则被轮训到时执行
              
              
threadOne
              
                .
              
              start
              
                (
              
              
                )
              
              
threadTwo
              
                .
              
              start
              
                (
              
              
                )
              
              
                #每个线程被创建时都拥有一个名字,使用'getName'方法输出线程的名字如下
              
              
                print
              
              
                (
              
              threadOne
              
                .
              
              getName
              
                (
              
              
                )
              
              
                )
              
              
                print
              
              
                (
              
              threadTwo
              
                .
              
              getName
              
                (
              
              
                )
              
              
                )
              
              
                ##Thread-1
              
              
                print
              
              
                (
              
              
                'after start thread'
              
              
                )
              
            
          

多线程之自定义线程类示例

            
              
                #!/usr/bin/env python
              
              
                #coding:utf-8
              
              
                #导入模块
              
              
                from
              
               threading 
              
                import
              
               Thread

              
                import
              
               time


              
                #自定义一个线程类myThreadClass继承父类Thread
              
              
                #实质是在原有Thread类的基础上增加自己的功能形成自定义的线程类
              
              
                class
              
              
                myThreadClass
              
              
                (
              
              Thread
              
                )
              
              
                :
              
              
                #重写run方法,因为父类Thread拥有run方法,此处为重写。
              
              
                def
              
              
                run
              
              
                (
              
              self
              
                )
              
              
                :
              
              
        time
              
                .
              
              sleep
              
                (
              
              
                10
              
              
                )
              
              
                print
              
              
                (
              
              
                'run方法创建了一个线程,我等了10s才现身'
              
              
                )
              
              
                try
              
              
                :
              
              
                if
              
               self
              
                .
              
              _target
              
                :
              
              
                self
              
                .
              
              _target
              
                (
              
              
                *
              
              self
              
                .
              
              _args
              
                ,
              
              
                **
              
              self
              
                .
              
              _kwargs
              
                )
              
              
                finally
              
              
                :
              
              
                # Avoid a refcycle if the thread is running a function with
              
              
                # an argument that has a member that points to the thread.
              
              
                del
              
               self
              
                .
              
              _target
              
                ,
              
               self
              
                .
              
              _args
              
                ,
              
               self
              
                .
              
              _kwargs
        

              
                def
              
              
                funcThree
              
              
                (
              
              
                )
              
              
                :
              
              
                print
              
              
                (
              
              
                'funcThree'
              
              
                )
              
              
                #执行myThreadClass类从Thread类继承的构造函数
              
              
threadThree 
              
                =
              
               myThreadClass
              
                (
              
              target
              
                =
              
              funcThree
              
                )
              
              
threadThree
              
                .
              
              start
              
                (
              
              
                )
              
              
                print
              
              
                (
              
              
                '主线程已经执行完毕'
              
              
                )
              
            
          

多线程之生产者与消费者模型示例一

producer.py(非正常)

            
              
                #!/usr/bin/env python
              
              
                #coding:utf-8
              
              
                #导入模块
              
              
                from
              
               threading 
              
                import
              
               Thread

              
                import
              
               time

              
                #导入队列模块的队列类
              
              
                from
              
               queue 
              
                import
              
               Queue

              
                #定义生产者类,向队列存放数据
              
              
                class
              
              
                producer
              
              
                (
              
              Thread
              
                )
              
              
                :
              
              
                #重写父类的构造函数__init__
              
              
                def
              
              
                __init__
              
              
                (
              
              self
              
                ,
              
              name
              
                ,
              
              queue
              
                )
              
              
                :
              
              
                #name:生产者的名字
              
              
                #queue:存放数据的容器
              
              
        self
              
                .
              
              __Name 
              
                =
              
               name
        self
              
                .
              
              __Queue 
              
                =
              
               queue
        
              
                #或Thread.__init__(self)
              
              
                super
              
              
                (
              
              producer
              
                ,
              
              self
              
                )
              
              
                .
              
              __init__
              
                (
              
              
                )
              
              
                #重写父类的run函数
              
              
                def
              
              
                run
              
              
                (
              
              self
              
                )
              
              
                :
              
              
                while
              
              
                True
              
              
                :
              
              
                #判断队列是否已满
              
              
                if
              
               self
              
                .
              
              __Queue
              
                .
              
              full
              
                (
              
              
                )
              
              
                :
              
              
                #满则等待1秒
              
              
                time
              
                .
              
              sleep
              
                (
              
              
                1
              
              
                )
              
              
                else
              
              
                :
              
              
                #未满则向队列加入数据
              
              
                self
              
                .
              
              __Queue
              
                .
              
              put
              
                (
              
              
                'someData'
              
              
                )
              
              
                print
              
              
                (
              
              
                '%s 向队列中放置了一个数据'
              
              
                %
              
              
                (
              
              self
              
                .
              
              __Name
              
                ,
              
              
                )
              
              
                )
              
              
                time
              
                .
              
              sleep
              
                (
              
              
                1
              
              
                )
              
              
        Thread
              
                .
              
              run
              
                (
              
              self
              
                )
              
              
                #定义消费者类 , 从队列取出数据  
              
              
                class
              
              
                consumer
              
              
                (
              
              Thread
              
                )
              
              
                :
              
              
                #重写父类的构造函数__init__
              
              
                def
              
              
                __init__
              
              
                (
              
              self
              
                ,
              
              name
              
                ,
              
              queue
              
                )
              
              
                :
              
              
                #name:生产者的名字
              
              
                #queue:存放数据的容器
              
              
        self
              
                .
              
              __Name 
              
                =
              
               name
        self
              
                .
              
              __Queue 
              
                =
              
               queue
        Thread
              
                .
              
              __init__
              
                (
              
              self
              
                )
              
              
                def
              
              
                run
              
              
                (
              
              self
              
                )
              
              
                :
              
              
                #判断队列是否已空
              
              
                if
              
               self
              
                .
              
              __Queue
              
                .
              
              empty
              
                (
              
              
                )
              
              
                :
              
              
                #空则等待1秒
              
              
            time
              
                .
              
              sleep
              
                (
              
              
                1
              
              
                )
              
              
                else
              
              
                :
              
              
                #未空则从队列拿出一个数据
              
              
            self
              
                .
              
              __Queue
              
                .
              
              get
              
                (
              
              
                )
              
              
                print
              
              
                (
              
              
                '%s 从队列中取走了一个数据'
              
              
                %
              
              
                (
              
              self
              
                .
              
              __Name
              
                ,
              
              
                )
              
              
                )
              
              
            time
              
                .
              
              sleep
              
                (
              
              
                1
              
              
                )
              
              
        Thread
              
                .
              
              run
              
                (
              
              self
              
                )
              
              
                #创建队列对象并设置队列最大为10。
              
              
                #队列特性:先进先出,线程安全的
              
              
queueObj 
              
                =
              
               Queue
              
                (
              
              maxsize
              
                =
              
              
                100
              
              
                )
              
              
                #使用xxx对数据结构(序列、列表等)上锁,同一时间仅允许一个线程对上锁的数据结构进行操作。
              
              
                #向队列存放数据
              
              
queueObj
              
                .
              
              put
              
                (
              
              
                '1'
              
              
                )
              
              
                #查看队列内容
              
              
                print
              
              
                (
              
              queueObj
              
                .
              
              queue
              
                )
              
              
                #使用queueObj.empty()判断队列时候为空
              
              
                print
              
              
                (
              
              queueObj
              
                .
              
              empty
              
                (
              
              
                )
              
              
                )
              
              
                #从队列取出数据
              
              
                print
              
              
                (
              
              queueObj
              
                .
              
              get
              
                (
              
              
                )
              
              
                )
              
              
                print
              
              
                (
              
              queueObj
              
                .
              
              queue
              
                )
              
              
                print
              
              
                (
              
              queueObj
              
                .
              
              empty
              
                (
              
              
                )
              
              
                )
              
              
                #使用队列类创建一个仓库对象queueObjTwo
              
              
queueObjTwo 
              
                =
              
               Queue
              
                (
              
              maxsize
              
                =
              
              
                100
              
              
                )
              
              
                #使用生产者类创建生产者对象。因为本质上是继承了线程类Thread,所以可以认为创建的生产者对象就等同于创建的新的线程
              
              
                #创建三个生产者
              
              
producerOne 
              
                =
              
               producer
              
                (
              
              
                'producerYiHao'
              
              
                ,
              
              queueObjTwo
              
                )
              
              
producerOne
              
                .
              
              start
              
                (
              
              
                )
              
              
producerTwo 
              
                =
              
               producer
              
                (
              
              
                'producerErHao'
              
              
                ,
              
              queueObjTwo
              
                )
              
              
producerTwo
              
                .
              
              start
              
                (
              
              
                )
              
              
producerThree 
              
                =
              
               producer
              
                (
              
              
                'producerSanHao'
              
              
                ,
              
              queueObjTwo
              
                )
              
              
producerThree
              
                .
              
              start
              
                (
              
              
                )
              
              
                print
              
              
                (
              
              queueObjTwo
              
                .
              
              queue
              
                )
              
              
                #使用消费者类创建消费者对象。因为本质上是继承了线程类Thread,所以可以认为创建的消费者对象就等同于创建的新的线程
              
              
                #创建二十个消费者
              
              
                for
              
               item 
              
                in
              
              
                range
              
              
                (
              
              
                20
              
              
                )
              
              
                :
              
              
    name 
              
                =
              
              
                'consumer%d'
              
              
                %
              
              
                (
              
              item
              
                ,
              
              
                )
              
              
    name 
              
                =
              
               consumer
              
                (
              
              name
              
                ,
              
              queueObjTwo
              
                )
              
              
    name
              
                .
              
              start
              
                (
              
              
                )
              
              
    
consumerOne 
              
                =
              
               consumer
              
                (
              
              
                'consumerYiHao'
              
              
                ,
              
              queueObjTwo
              
                )
              
              
consumerOne
              
                .
              
              start
              
                (
              
              
                )
              
              
                print
              
              
                (
              
              queueObjTwo
              
                .
              
              queue
              
                )
              
            
          

消费者生产者模型优点
解耦:令一个程序的各个部分之间关联性降到最低。

函数式编程实现生产者与消费者模型

producerDemoTwo.py

            
              
                #!/usr/bin/env python
              
              
                #coding:utf-8
              
              
                import
              
               threading

              
                import
              
               time

              
                import
              
               queue

              
                import
              
               random


              
                def
              
              
                producer
              
              
                (
              
              name
              
                ,
              
              que
              
                )
              
              
                :
              
              
                while
              
              
                True
              
              
                :
              
              
                if
              
               que
              
                .
              
              qsize
              
                (
              
              
                )
              
              
                <
              
              
                3
              
              
                :
              
              
            que
              
                .
              
              put
              
                (
              
              
                'baozi'
              
              
                )
              
              
                print
              
              
                (
              
              
                '%s make a baozi...'
              
              
                %
              
              name
              
                )
              
              
                else
              
              
                :
              
              
                print
              
              
                (
              
              
                '有三个包子,吃了在做'
              
              
                )
              
              
                #随机等待一到五秒
              
              
        time
              
                .
              
              sleep
              
                (
              
              random
              
                .
              
              randrange
              
                (
              
              
                5
              
              
                )
              
              
                )
              
              
                def
              
              
                consumer
              
              
                (
              
              name
              
                ,
              
              que
              
                )
              
              
                :
              
              
                while
              
              
                True
              
              
                :
              
              
                #使用try捕捉错误异常,若队列为空,则打印异常输出,此时consumer线程不再中断。没有捕捉错误异常且队列为空时,consumer线程抛出异常并中断
              
              
                try
              
              
                :
              
              
                #使用'que.get()'时,若队列中无数据,则阻塞;使用'que.get_nowait()'时,若队列中无数据,则抛出异常
              
              
            que
              
                .
              
              get_nowait
              
                (
              
              
                )
              
              
                print
              
              
                (
              
              
                '%s eat a baozi'
              
              
                %
              
              name
              
                )
              
              
                #随机等待一到三秒
              
              
                except
              
               Exception
              
                :
              
              
                print
              
              
                (
              
              u
              
                'baozi 吃光了'
              
              
                )
              
              
        time
              
                .
              
              sleep
              
                (
              
              random
              
                .
              
              randrange
              
                (
              
              
                5
              
              
                )
              
              
                )
              
              
        

q 
              
                =
              
              queue
              
                .
              
              Queue
              
                (
              
              
                )
              
              
p1 
              
                =
              
               threading
              
                .
              
              Thread
              
                (
              
              target
              
                =
              
              producer
              
                ,
              
              args
              
                =
              
              
                [
              
              
                'chef1'
              
              
                ,
              
              q
              
                ]
              
              
                )
              
              
p2 
              
                =
              
               threading
              
                .
              
              Thread
              
                (
              
              target
              
                =
              
              producer
              
                ,
              
              args
              
                =
              
              
                [
              
              
                'chef2'
              
              
                ,
              
              q
              
                ]
              
              
                )
              
              
p1
              
                .
              
              start
              
                (
              
              
                )
              
              
p2
              
                .
              
              start
              
                (
              
              
                )
              
              
c1 
              
                =
              
               threading
              
                .
              
              Thread
              
                (
              
              target
              
                =
              
              consumer
              
                ,
              
              args
              
                =
              
              
                [
              
              
                'consu1'
              
              
                ,
              
              q
              
                ]
              
              
                )
              
              
c2 
              
                =
              
               threading
              
                .
              
              Thread
              
                (
              
              target
              
                =
              
              consumer
              
                ,
              
              args
              
                =
              
              
                [
              
              
                'consu2'
              
              
                ,
              
              q
              
                ]
              
              
                )
              
              
c1
              
                .
              
              start
              
                (
              
              
                )
              
              
c2
              
                .
              
              start
              
                (
              
              
                )
              
            
          

多线程开发之线程锁

线程锁中的threading.Lock和threading.Rlock

线程安全:
因为多个线程之间共享一份内存数据,为了防止出现多个线程同时修改一份内存数据的情况,需要使用线程锁。
定义递归锁对象,可以在锁内继续加锁而不会出现阻塞现象。
lock = threading.RLock()
定义线程锁对象,同时允许有四个线程对同一份数据进行操作。
lock = threading.BoundedSemaphore(4)

            
              
                #!/usr/bin/env python
              
              
                #coding:utf-8
              
              
                import
              
               threading

              
                import
              
               time

              
                #定义全局变量num,多线程同时启动时,共享内存数据全局变量num
              
              
num 
              
                =
              
              
                0
              
              
                #定义函数
              
              
                def
              
              
                run
              
              
                (
              
              n
              
                )
              
              
                :
              
              
                #声明变量num为全局变量
              
              
    time
              
                .
              
              sleep
              
                (
              
              
                1
              
              
                )
              
              
                global
              
               num
    
              
                #获取锁,当前线程独占对该数据的操作
              
              
                #锁的位置应当仅放置于对数据操作的代码段外面。该代码段将变成串行线程。
              
              
    lock
              
                .
              
              acquire
              
                (
              
              
                )
              
              
    num 
              
                +=
              
              
                1
              
              
                print
              
              
                (
              
              num
              
                )
              
              
    lock
              
                .
              
              release
              
                (
              
              
                )
              
              
                #run('dd')
              
              
                #定义线程锁对象
              
              
lock 
              
                =
              
               threading
              
                .
              
              Lock
              
                (
              
              
                )
              
              
                #定义递归锁对象,可以在锁内继续加锁而不会出现阻塞现象。
              
              
                #lock = threading.RLock()
              
              
                #定义线程锁对象,同时允许有四个线程对同一份数据进行操作。
              
              
                #lock = threading.BoundedSemaphore(4)
              
              
                #生成十个线程
              
              
                for
              
               i 
              
                in
              
              
                range
              
              
                (
              
              
                100
              
              
                )
              
              
                :
              
              
    t 
              
                =
              
               threading
              
                .
              
              Thread
              
                (
              
              target
              
                =
              
              run
              
                ,
              
              args
              
                =
              
              
                (
              
              i
              
                ,
              
              
                )
              
              
                )
              
              
    t
              
                .
              
              start
              
                (
              
              
                )
              
              
                #此时由于多个线程同时执行函数run修改全局变量num,num的值容易出现异常。
              
              
                #锁内加锁,程序会出现阻塞(死锁)现象。出现该问题时,使用'lock = threading.RLock()'递归锁可以解决.
              
            
          

多线程开发之event事件

            
              
                #!/usr/bin/env python
              
              
                #coding:utf-8
              
              
                import
              
               threading

              
                import
              
               time

              
                #实现两个线程之间通过event事件来进行交互。
              
              
                #定义生产者
              
              
                def
              
              
                producer
              
              
                (
              
              
                )
              
              
                :
              
              
                print
              
              
                (
              
              u
              
                '等人来买包子'
              
              
                )
              
              
                #等待事件,阻塞状态
              
              
    event
              
                .
              
              wait
              
                (
              
              
                )
              
              
                #使用'isSet'判断事件状态(是否为true).此时不存在阻塞状态
              
              
                #print(event.isSet())
              
              
                #清空事件时间状态
              
              
    event
              
                .
              
              clear
              
                (
              
              
                )
              
              
                print
              
              
                (
              
              u
              
                '刚刚有个抠脚大汉来买包子了'
              
              
                )
              
              
                print
              
              
                (
              
              u
              
                'dang dang dang ,开工做包子啦'
              
              
                )
              
              
                #三秒过后
              
              
    time
              
                .
              
              sleep
              
                (
              
              
                10
              
              
                )
              
              
                print
              
              
                (
              
              u
              
                '啦啦啦,包子出锅啦'
              
              
                )
              
              
    
    event
              
                .
              
              
                set
              
              
                (
              
              
                )
              
              
                print
              
              
                (
              
              u
              
                '歪,妖妖灵吗,包子好了,趁热买吧'
              
              
                )
              
              
                #定义消费者
              
              
                def
              
              
                consumer
              
              
                (
              
              
                )
              
              
                :
              
              
                print
              
              
                (
              
              u
              
                '俺去买包子'
              
              
                )
              
              
                #设置标志,触发事件
              
              
    event
              
                .
              
              
                set
              
              
                (
              
              
                )
              
              
                print
              
              
                (
              
              u
              
                '(顾客)俺刚刚跟厨师说做俩包子,俺要买'
              
              
                )
              
              
    time
              
                .
              
              sleep
              
                (
              
              
                3
              
              
                )
              
              
                while
              
              
                True
              
              
                :
              
              
                if
              
               event
              
                .
              
              isSet
              
                (
              
              
                )
              
              
                :
              
              
                print
              
              
                (
              
              
                '看表:时间到了'
              
              
                )
              
              
                break
              
              
                else
              
              
                :
              
              
                print
              
              
                (
              
              
                '等待中,肚子咕咕叫'
              
              
                )
              
              
            time
              
                .
              
              sleep
              
                (
              
              
                1
              
              
                )
              
              
    
    event
              
                .
              
              wait
              
                (
              
              
                )
              
              
                print
              
              
                (
              
              u
              
                '俺收到通知,:您的包子出锅啦,赶紧趁热去买吧'
              
              
                )
              
              
                #定义事件触发,消费者触发事件去生产者那边买包子
              
              
event 
              
                =
              
               threading
              
                .
              
              Event
              
                (
              
              
                )
              
              
p1 
              
                =
              
               threading
              
                .
              
              Thread
              
                (
              
              target
              
                =
              
              producer
              
                )
              
              
p2 
              
                =
              
               threading
              
                .
              
              Thread
              
                (
              
              target
              
                =
              
              consumer
              
                )
              
              
p1
              
                .
              
              start
              
                (
              
              
                )
              
              
p2
              
                .
              
              start
              
                (
              
              
                )
              
            
          

更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论