Python个人学习笔记二

一  线程简介

说道python线程,其封装和方法也比较多样,使用比较方便。目前主要的有三种方式。

1.1

方法一:通过使用thread模块中的函数创建新线程。

但是注意在3.4版本里面,该函数已经不再thread模块之中,若要引用需要导入

import _dummy_thread.其函数实现源码为:

def start_new_thread(function, args, kwargs={}):
    """Dummy implementation of _thread.start_new_thread().

    Compatibility is maintained by making sure that ``args`` is a
    tuple and ``kwargs`` is a dictionary.  If an exception is raised
    and it is SystemExit (which can be done by _thread.exit()) it is
    caught and nothing is done; all other exceptions are printed out
    by using traceback.print_exc().

    If the executed function calls interrupt_main the KeyboardInterrupt will be
    raised when the function returns.

    """
    if type(args) != type(tuple()):
        raise TypeError("2nd arg must be a tuple")
    if type(kwargs) != type(dict()):
        raise TypeError("3rd arg must be a dict")
    global _main
    _main = False
    try:
        function(*args, **kwargs)
    except SystemExit:
        pass
    except:
        import traceback
        traceback.print_exc()
    _main = True
    global _interrupt
    if _interrupt:
        _interrupt = False
        raise KeyboardInterrupt

使用的时候比如:

def run(n):
    for i in range(n):
        print (i)
_dummy_thread.start_new_thread (run, (4,))
# 注意第二个参数一定要是元组的形式

1.2

方法二:使用threading.Thread直接在线程中运行函数。

其定义在threading模块中,本例只说明其中重要几个函数

class Thread:
    """A class that represents a thread of control.
    This class can be safely subclassed in a limited fashion. There are two ways
    to specify the activity: by passing a callable object to the constructor, or
    by overriding the run() method in a subclass
  #......................
  def is_alive(self):#该函数返回当前线程是否存活状态,比较重要。
        #Return whether the thread is alive.
  def ident(self):#该函数返回当前线程的ID标示符,类似于TID
        #Thread identifier of this thread or None if it has not been started. This is a nonzero integer.
  def run(self):#该函数是线程的运行函数,可以自己覆盖重写,也可以直接进行默认调用。
        #Method representing the thread's activity.
  def start(self):#线程启动函数,创建的线程自己不会启动,必须自己手动启动。
        #Start the thread's activity.
  def join(self, timeout=None):#该函数实现等待到运行结束,类似于同步也叫线程合并,因为join之后线程结束
                               #才运行下一行代码,待会代码实例测试。
        #Wait until the thread terminates.
  def _wait_for_tstate_lock(self, block=True, timeout=-1):#线程自身带了互斥锁

  def setDaemon(self):#设置线程属性状态,若果设置为True主线程结束,子线程就被主线程结束,
                      #若是False则必须等待到所有子线程结束,主线程才结束退出。
import threading

def running(x, y):
    for i in range(x, y):
        print (i)
for i in range(3):
    t1 = threading.Thread(target=running, args=(1 * i, 10 * (i + 1)))
    t1.start()
    t1.join()

采用join方法结果

0
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

若不采用则线程竞争出现毫无规律数字,甚至出现重复,因为这里没有进行互斥

0
1
1
2
3
4
5
6
7
8
9
2
2
3
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

1.3

方法三:通过继承threading.Thread创建线程

class mz_thread(threading.Thread):  
    def __init__(self, num):  
        threading.Thread.__init__(self)  
        self.num = num  
    def run(self):
        while True:
            print ('I am', self.num)  
for i in range(10):
    t = mz_thread(i)
    t.start()

结果

I am 9
I am 0
I am 8
I am 1
I am 6
I am 7
I am 5
I am 2
I am 4
I am 9
I am 4
I am 9
I am 0
I am 8
I am 1
I am 6
I am 3
I am 7
I am 5
I am 2
I am 4
I am 9
I am 0
I am 8
I am 7
I am 5
I am 2
I am 4
I am 9
I am 0
I am 8
I am 1
I am 6
I am 3
I am 7
I am 7
I am 5
I am 2
I am 4
I am 9

二   利用EVENT类的实现线程之间同步

首先看看Event类的定义代码

class Event:
    """Class implementing event objects.

    Events manage a flag that can be set to true with the set() method and reset
    to false with the clear() method. The wait() method blocks until the flag is
    true.  The flag is initially false.

    """

    # After Tim Peters' event class (without is_posted())

    def __init__(self):
        self._cond = Condition(Lock())
        self._flag = False #很关键默认创建之后信号状态为False

    def _reset_internal_locks(self):
        # private!  called by Thread._reset_internal_locks by _after_fork()
        self._cond.__init__()

    def is_set(self):#很关键,获取当前事件信号状态,返回值为True和False
        """Return true if and only if the internal flag is true."""
        return self._flag

    isSet = is_set

    def set(self):#很关键,将事件信号设置为有信号状态
        """Set the internal flag to true.

        All threads waiting for it to become true are awakened. Threads
        that call wait() once the flag is true will not block at all.

        """
        self._cond.acquire()
        try:
            self._flag = True
            self._cond.notify_all()
        finally:
            self._cond.release()

    def clear(self):#很关键,将事件信号设置为无信号状态
        """Reset the internal flag to false.

        Subsequently, threads calling wait() will block until set() is called to
        set the internal flag to true again.

        """
        self._cond.acquire()
        try:
            self._flag = False
        finally:
            self._cond.release()

    def wait(self, timeout=None):#很关键,进行同步信号等待函数
        """Block until the internal flag is true.

        If the internal flag is true on entry, return immediately. Otherwise,
        block until another thread calls set() to set the flag to true, or until
        the optional timeout occurs.

        When the timeout argument is present and not None, it should be a
        floating point number specifying a timeout for the operation in seconds
        (or fractions thereof).

        This method returns the internal flag on exit, so it will always return
        True except if a timeout is given and the operation times out.

        """
        self._cond.acquire()
        try:
            signaled = self._flag
            if not signaled:
                signaled = self._cond.wait(timeout)
            return signaled
        finally:
            self._cond.release()

//使用event进行同步,那么必须在多线程下,同时也得创建多个event对象数组。

注意这里python数组这样定义和动态创建。

INT_EVENTS_LIST = []
for i in range(3):
        INT_EVENTS_LIST.append(threading.Event())
        INT_EVENTS_LIST[0].set()#调用的时候也是采用下标索引方式实现。

测试同步代码

class mz_thread(threading.Thread):
    m_Src = 0
    m_Des = 0
    m_iIndex = 0
    def __init__(self, numSrc, numDes, iIndex):
        threading.Thread.__init__(self)
        self.m_Src = numSrc
        self.m_Des = numDes
        self.m_iIndex = iIndex
    def run(self):
        while self.m_Src < self.m_Des:
            INT_EVENTS_LIST[self.m_iIndex].wait()
            print ('I am thread ', self.m_iIndex, '--Num--', self.m_Src)
            INT_EVENTS_LIST[self.m_iIndex].clear()
            INT_EVENTS_LIST[(self.m_iIndex + 1) % 3].set()
INT_EVENTS_LIST = []
THREAD_ARRAY = []
if __name__ == '__main__':
    print('Main Thread Run :', __name__)
    for i in range(3):
        INT_EVENTS_LIST.append(threading.Event())
    INT_EVENTS_LIST[0].set()
    for iThreadIndex in range(3):
        THREAD_ARRAY.append(mz_thread(iThreadIndex * 3, (iThreadIndex + 1) * 3, iThreadIndex))
        THREAD_ARRAY[iThreadIndex].start()

结果

I am thread  0 --Num-- 0
I am thread  1 --Num-- 3
I am thread  2 --Num-- 6
I am thread  0 --Num-- 0
I am thread  1 --Num-- 3
I am thread  2 --Num-- 6
I am thread  0 --Num-- 0
I am thread  1 --Num-- 3
I am thread  2 --Num-- 6
I am thread  0 --Num-- 0
I am thread  1 --Num-- 3
I am thread  2 --Num-- 6
I am thread  0 --Num-- 0
I am thread  1 --Num-- 3
I am thread  2 --Num-- 6
I am thread  0 --Num-- 0
I am thread  1 --Num-- 3
I am thread  2 --Num-- 6
I am thread  0 --Num-- 0
I am thread  1 --Num-- 3
I am thread  2 --Num-- 6
I am thread  0 --Num-- 0
I am thread  1 --Num-- 3
I am thread  2 --Num-- 6
I am thread  0 --Num-- 0
I am thread  1 --Num-- 3
I am thread  2 --Num-- 6
I am thread  0 --Num-- 0
I am thread  1 --Num-- 3
I am thread  2 --Num-- 6
I am thread  0 --Num-- 0
I am thread  1 --Num-- 3
I am thread  2 --Num-- 6
I am thread  0 --Num-- 0
I am thread  1 --Num-- 3
I am thread  2 --Num-- 6
I am thread  0 --Num-- 0
I am thread  1 --Num-- 3
I am thread  2 --Num-- 6
I am thread  0 --Num-- 0
I am thread  1 --Num-- 3
I am thread  2 --Num-- 6
I am thread  0 --Num-- 0
I am thread  1 --Num-- 3
I am thread  2 --Num-- 6

三  说明

在Python里面同步的方式除了使用Event事件也可以直接使用Queue队列。因为

Python队列Queue操作本身进行了原语封装,实现了同步访问。也可以自定义标志

或者相关变量来访问。至于线程互斥那方法就更多了。下一节将会学习。

时间: 2024-12-19 05:35:10

Python个人学习笔记二的相关文章

2. 蛤蟆Python脚本学习笔记二基本命令畅玩

2. 蛤蟆Python脚本学习笔记二基本命令畅玩 本篇名言:"成功源于发现细节,没有细节就没有机遇,留心细节意味着创造机遇.一件司空见惯的小事或许就可能是打开机遇宝库的钥匙!" 下班回家,咱先来看下一些常用的基本命令. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/48092873 1.  数字和表达式 看下图1一就能说明很多问题: 加法,整除,浮点除,取模,幂乘方等.是不是很直接也很粗暴. 关于上限,蛤蟆不太清楚

Python——追加学习笔记(二)

文件处理 # 文件内移动 seek()方法可以在文件中移动文件指针到不同的位置,offset字节代表相对于某个位置偏移量,默认为0,代表从文件开头算起,1代表从当前位置算起,2代表从文件末尾算起. seek()经常用来重设文件位置指针. eg. >>> f.name 'anaconda-ks.cfg' >>> f.next() '#version=DEVEL\n' >>> f.next() '# System authorization informa

python之数据类型(学习笔记二)

python之数据类型(学习笔记二) 在Python中,能够直接处理的数据类型有以下几种: (1)整数 Python可以处理任意大小的整数,当然包括负整数,在程序中的表示方法和数学上的写法一模一样,例 如: 1 , 100 , ‐8080 , 0 ,等等. 计算机由于使用二进制,所以,有时候用十六进制表示整数比较方便,十六进制用 0x 前缀和0-9,a-f表示,例 如: 0xff00 , 0xa5b4c3d2 ,等等. (2)浮点数 浮点数也就是小数,之所以称为浮点数,是因为按照科学记数法表示时

Python学习笔记&lt;二&gt;:列表、元组、字典

1 列表和元组 可以将列表和元组当成普通的"数组",它能保存任意数量任意类型的Python 对象.和数组一样,通过从0 开始的数字索引访问元素,但是列表和元组可以存储不同类型的对象. 列表和元组有几处重要的区别.列表元素用中括号( [ ])包裹,元素的个数及元素的值可以改变.元组元素用小括号(( ))包裹,不可以更改(尽管他们的内容可以).元组可以看成是只读的列表.通过切片运算( [ ] 和 [ : ] )可以得到子集,这一点与字符串的使用方法一样. 举例如下: >>>

[Python][MachineLeaning]Python Scikit-learn学习笔记1-Datasets&amp;Estimators

Scikit-learn官网:http://scikit-learn.org/stable/index.html Datasets 标准的数据集格式为一组多维特征向量组成的集合.数据集的标准形状(shape)为二维数组(samples, features),其中samples表示数据集大小,features表示其中特征向量的维数. 使用时可使用shape方法查看数据集 >>> from sklearn import datasets >>> iris = dataset

Caliburn.Micro学习笔记(二)----Actions

Caliburn.Micro学习笔记(二)----Actions 上一篇已经简单说了一下引导类和简单的控件绑定 我的上一个例子里的button自动匹配到ViewModel事件你一定感觉很好玩吧 今天说一下它的Actions,看一下Caliburn.Micro给我们提供了多强大的支持 我们还是从做例子开始 demo的源码下载在文章的最后 例子1.无参数方法调用 点击button把textBox输入的文本弹出来 如果textbox里没有文本button不可点,看一下效果图 看一下前台代码 <Stac

小猪的数据结构学习笔记(二)

小猪的数据结构学习笔记(二) 线性表中的顺序表 本节引言: 在上个章节中,我们对数据结构与算法的相关概念进行了了解,知道数据结构的 逻辑结构与物理结构的区别,算法的特性以及设计要求;还学了如何去衡量一个算法 的好坏,以及时间复杂度的计算!在本节中我们将接触第一个数据结构--线性表; 而线性表有两种表现形式,分别是顺序表和链表;学好这一章很重要,是学习后面的基石; 这一节我们会重点学习下顺序表,在这里给大家一个忠告,学编程切忌眼高手低,看懂不代表自己 写得出来,给出的实现代码,自己要理解思路,自己

JavaScript--基于对象的脚本语言学习笔记(二)

第二部分:DOM编程 1.文档象模型(DOM)提供了访问结构化文档的一种方式,很多语言自己的DOM解析器. DOM解析器就是完成结构化文档和DOM树之间的转换关系. DOM解析器解析结构化文档:将磁盘上的结构化文档转换成内存中的DOM树 从DOM树输出结构化文档:将内存中的DOM树转换成磁盘上的结构化文档 2.DOM模型扩展了HTML元素,为几乎所有的HTML元素都新增了innerHTML属性,该属性代表该元素的"内容",即返回的某个元素的开始标签.结束标签之间的字符串内容(不包含其它

马哥学习笔记二十四——分布式复制快设备drbd

DRBD: 主从 primary: 可执行读.写操作 secondary: 文件系统不能挂载 DRBD: dual primay, 双主(基于集群文件系统的高可用集群) 磁盘调度器:合并读请求,合并写请求: Procotol:drbd数据同步协议 A: Async, 异步  数据发送到本机tcp/ip协议栈 B:semi sync, 半同步  数据发送到对方tcp/ip协议 C:sync, 同步  数据到达对方存储设备 DRBD Source: DRBD资源 资源名称:可以是除了空白字符外的任意