线程的那点事情

1.线程安全

首先我们知道线程是共享资源的,在这个基础上我们提出一个问题,如果我们有一个变量a = 0

然后10个线程都是给它+1的 然后我们执行这个10个线程,最后a = 10吗?

我们先看下面的代码

 1 __author__ = ‘Rico‘
 2 #_*_coding:utf-8_*_
 3 from threading import Thread
 4 a = 0
 5 class Plusone(Thread):
 6     def __init__(self):
 7         super(Plusone,self).__init__()
 8     def run(self):
 9         global  a
10         a += 1
11
12 for i in range(30):
13     temp =  Plusone()
14     temp.start()
15
16 print a

如果没错的的应该输入的是30

但是---》

结果是29

当然这不是每次都会出现的,是不固定的,看电脑的配置的,和线程的个数

由此 我们知道 变量之所以没有得到我们想要的值,是因为线程之间抢占了变量,导致了问题的发生 --->结论:Python不是一个线程安全的语言

那么我们要自己保证线程安全了那么引出了下面的概念

2线程锁

我们去买衣服的时候,试衣间里面会不会出现两个人?并不会。为什么呢? 因为每个人进去之后会反锁门,走的时候才打开。这就是线程锁的概念

我们修改下run函数

1 def run(self):
2         lock.acquire()
3         global  a
4         a += 1
5         print a
6         lock.release()
lock.acquire()#在执行这个时候,线程会独占cpulock.release()#释放在执行两个操作的时候之间其实就是单线程了

Python有一个叫全局解释器锁的东西我们大家都知道--进行cpu操作的时候,因为全局解释器锁的原因你起了一个多线程,其实还是一个单线程,其他的线程其实都在切片
 1 __author__ = ‘Rico‘
 2 #_*_coding:utf-8_*_
 3 from threading import Thread,Lock
 4 import  time
 5 a = 0
 6 class Plusone(Thread):
 7     def __init__(self,name):
 8         self.__name = name
 9         super(Plusone,self).__init__()
10     def run(self):
11         global  a
12         lock.acquire()
13         a += 1
14         lock.release()
15         print "%s\n" % a
16 lock =Lock()
17
18 for i in range(200):
19     temp =  Plusone(i)
20     temp.start()
21
22 print a

我们在跑这个代码的时候,就可以感受到了 无论你开多少线程 最后还是顺序的切片 但是如果你把run函数变成这样

def run(self):
        global  a
        lock.acquire()
        a += 1
        lock.release()
        time.sleep(1)
        print "%s\n" % a

cpu默认都之拿来100条指令 当加入了sleep(1) 就不等了 直接切了

3信号量 同时允许及格线程访问同一个数据

 1 __author__ = ‘Rico‘
 2 #_*_coding:utf-8_*_
 3 from threading import Thread,Lock,BoundedSemaphore
 4 import  time
 5 a = 0
 6 class Plusone(Thread):
 7     def __init__(self,name):
 8         self.__name = name
 9         super(Plusone,self).__init__()
10     def run(self):
11         time.sleep(1)
12         global  a
13         samp.acquire()
14         a += 1
15         print "%s" % a
16         samp.release()
17 samp = BoundedSemaphore(10)
18 for i in range(200):
19     temp =  Plusone(i)
20     temp.start()
21
22 print a
时间: 2024-10-25 15:45:07

线程的那点事情的相关文章

ios 独立创建一条线程,去做些事情

- (void)startLoop { [NSThread detachNewThreadSelector:@selector(loopMethod) toTarget:self withObject:nil]; } - (void)loopMethod { [NSTimer scheduledTimerWithTimeInterval:3.0f target:self selector:@selector(toDo) userInfo:nil repeats:YES]; NSRunLoop *

线程的那点事情02 --事件

还是卖包子的故事, 我们在生产者消费者模型里面,消费者一直问有没有包子,生产者一直生产包子 那么可不可以这样,消费者过来问:有没有包子的时候,告诉他没有,等过会做好了,叫你. 我们可以通过event来做线程间信号传递 1 __author__ = 'Rico' 2 #coding:utf-8 3 4 import threading 5 import time 6 7 8 def Producer(): 9 print 'cook:wait for somebody' 10 event.wait

POSIX 线程详解(经典必看)

总共三部分: 第一部分:POSIX 线程详解                                   Daniel Robbins ([email protected]), 总裁/CEO, Gentoo Technologies, Inc.  2000 年 7 月 01 日 第二部分:通用线程:POSIX 线程详解,第 2部分       Daniel Robbins ([email protected]), 总裁/CEO, Gentoo Technologies, Inc.  20

HandlerThread 创建一个异步的后台线程

使用HandlerThread几大优点: 1.制作一个后台异步线程,需要的时候就可以丢一个任务给它,使用比较灵活; 2.Android系统提供的,使用简单方便,内部自己封装了Looper+Handler机制; 3.可以代替Thread + Looper + Handler的写法; 4.可以避免项目中随处可见的 new Thread().start(),增加系统开销; 使用HandlerThread注意: 1.不要执行太耗时(一般情况不要超过100ms级别的)的任务,如果太耗时可能会阻塞其他的任务

JVM最多支持多少个线程?

JVM最多支持多少个线程? McGovernTheory在StackOverflow提了这样一个问题: Java虚拟机最多支持多少个线程?跟虚拟机开发商有关么?跟操作系统呢?还有其他的因素吗? Eddie的回答: 这取决于你使用的CPU,操作系统,其他进程正在做的事情,你使用的Java的版本,还有其他的因素.我曾经见过一台 Windows服务器在宕机之前有超过6500个线程.当然,大多数线程什么事情也没有做.一旦一台机器上有差不多6500个线程(Java里面),机器 就会开始出问题,并变得不稳定

关于线程中断的总结

在Core Java中有这样一句话:"没有任何语言方面的需求要求一个被中断的程序应该终止.中断一个线程只是为了引起该线程的注意,被中断线程可以决定如何应对中断 " 线程中断在线程生命周期中的作用: 线程状态 : Java虚拟机将线程运行过程分成四种状态 : (1) New 新生:(2) Runnable 可运行:(3) Blocked 阻塞:(4) Dead 死亡. 值得注意的是: 线程的可运行状态并不代表线程一定在运行(runnable != running ) . 大家都知道:所有

mysql   线程池

工作原理 根据连接id将连接分配到线程组中,线程组中的listener线程监控任务并将事务类型的任务放入优先队列,非事务任务放入普通队列, worker线程优先将优先队列中的任务处理掉再处理普通队列中的任务,线程组中worker线程循环取出任务,执行,返回结果. 在线程组之外有一个timer线程,主要做以下事情. 1.监控线程组的状态,如果监控到线程组中的线程不够用,就唤醒或者创建线程. 2.kill 超时连接线程 # 线程池有关的参数变量: thread_concurrency        

C#中的线程(二) 线程同步基础

1.同步要领 下面的表格列展了.NET对协调或同步线程动作的可用的工具:                       简易阻止方法 构成 目的 Sleep 阻止给定的时间周期 Join 等待另一个线程完成                       锁系统 构成 目的 跨进程? 速度 lock 确保只有一个线程访问某个资源或某段代码. 否 快 Mutex 确保只有一个线程访问某个资源或某段代码.可被用于防止一个程序的多个实例同时运行. 是 中等 Semaphore 确保不超过指定数目的线程访问某

netty源码分析之揭开reactor线程的面纱(二)

如果你对netty的reactor线程不了解,建议先看下上一篇文章netty源码分析之揭开reactor线程的面纱(一),这里再把reactor中的三个步骤的图贴一下 reactor线程 我们已经了解到netty reactor线程的第一步是轮询出注册在selector上面的IO事件(select),那么接下来就要处理这些IO事件(process selected keys),本篇文章我们将一起来探讨netty处理IO事件的细节 我们进入到reactor线程的 run 方法,找到处理IO事件的代