python的进程线程和协程_python成长之路 :线程、进程和协程

python线程

进程与线程的历史

我们都知道计算机是由硬件和软件组成的。硬件中的CPU是计算机的核心,它承担计算机的所有任务。 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资源的管理和分配、任务的调度。 程序是运行在系统上的具有某种功能的软件,比如说浏览器,音乐播放器等。 每次执行程序的时候,都会完成一定的功能,比如说浏览器帮我们打开网页,为了保证其独立性,就需要一个专门的管理和控制执行程序的数据结构——进程控制 块。 进程就是一个程序在一个数据集上的一次动态执行过程。 进程一般由程序、数据集、进程控制块三部分组成。我们编 写的程序用来描述进程要完成哪些功能以及如何完成;数据集则是程序在执行过程中所需要使用的资源;进程控制块用来记录进程的外部特征,描述进程的执行变化 过程,系统可以利用它来控制和管理进程,它是系统感知进程存在的唯一标志。

在早期的操作系统里,计算机只有一个核心,进程执行程序的最小单位,任务调度采用时间片轮转的抢占式方式进行进程调度。每个进程都有各自的一块独立的内 存,保证进程彼此间的内存地址空间的隔离。 随着计算机技术的发展,进程出现了很多弊端,一是进程的创建、撤销和切换的开销比较大,二是由于对称多处理机(对称多处理机 (SymmetricalMulti-Processing)又叫SMP,是指在一个计算机上汇集了一组处理器(多CPU),各CPU之间共享内存子系统 以及总线结构)的出现,可以满足多个运行单位,而多进程并行开销过大。 这个时候就引入了线程的概念。 线程也叫轻量级进程,它是一个基本的CPU执行单元,也是程序执行过程中的最小单元,由线程ID、程序计数器、寄存器集合 和堆栈共同组成。线程的引入减小了程序并发执行时的开销,提高了操作系统的并发性能。 线程没有自己的系统资源,只拥有在运行时必不可少的资源。但线程可以与同属与同一进程的其他线程共享进程所拥有的其他资源。

进程与线程之间的关系

线程是属于进程的,线程运行在进程空间内,同一进程所产生的线程共享同一内存空间,当进程退出时该进程所产生的线程都会被强制退出并清除。线程可与属于同 一进程的其它线程共享进程所拥有的全部资源,但是其本身基本上不拥有系统资源,只拥有一点在运行中必不可少的信息(如程序计数器、一组寄存器和栈)。

1 #!/usr/bin/env python

2 #-*- coding:utf-8 -*-

3 importthreading4 importtime,datetime5

6 defshow(arg):7 time.sleep(5)8 print('thread'+str(arg),time.time())9

10

11 for i in range(4):12 t = threading.Thread(target=show, args=(i,))13 #t.setName('name%s' % i)

14 #print(t.name)

15 #t.setDaemon(False) #默认是False, 如果改成True,主线程不等待子线程

16

17 t.start()18 t.run() #立即执行

19 t.join(2)20 print('main thread stop')

上述代码创建了10个“前台”线程,然后控制器就交给了CPU,CPU根据指定算法进行调度,分片执行指令。

更多方法:

start            线程准备就绪,等待CPU调度

setName      为线程设置名称

getName      获取线程名称

setDaemon   设置为后台线程或前台线程(默认为False)

如果是后台线程,主线程执行过程中,后台线程也在进行,主线程执行完毕后,后台线程不论成功与否,均停止

如果是前台线程,主线程执行过程中,前台线程也在进行,主线程执行完毕后,等待前台线程也执行完成后,程序停止

join              逐个执行每个线程,执行完毕后继续往下执行,该方法使得多线程变得无意义

run              线程被cpu调度后自动执行线程对象的run方法

线程锁threading.RLock和threading.Lock

我们使用线程对数据进行操作的时候,如果多个线程同时修改某个数据,可能会出现不可预料的结果,为了保证数据的准确性,引入了锁的概念

例:假设列表A的所有元素就为0,当一个线程从前向后打印列表的所有元素,另外一个线程则从后向前修改列表的元素为1,那么输出的时候,列表的元素就会一部分为0,一部分为1,这就导致了数据的不一致。锁的出现解决了这个问题。

1 #未加锁

2 importthreading3 importtime4

5 gl_num =06

7 defshow(arg):8 globalgl_num9 time.sleep(1)10 gl_num += 1

11 print(gl_num)12

13 for i in range(10):14 t = threading.Thread(target=show, args=(i,))15 t.start()16

17 print('main thread stop')

未加锁代码

1 线程锁2 importthreading3 importtime4

5 gl_num =06

7 lock = threading.RLock() #获取一个锁的对象

8

9 defFunc():10 lock.acquire() #创建一把锁

11 global gl_num #声明全局变量

12 gl_num +=1

13 time.sleep(1)14 print(gl_num)15 lock.release() #更改完释放锁

16

17 for i in range(10):18 t = threading.Thread(target=Func) #利用线程执行,执行10次 结果1,2,3,4,5,6.。

19 t.start()

线程锁

threading.Event

Event是线程间通信最间的机制之一:一个线程发送一个event信号,其他的线程则等待这个信号。用于主线程控制其他线程的执行。 Events 管理一个flag,这个flag可以使用set()设置成True或者使用clear()重置为False,wait()则用于阻塞,在flag为 True之前。flag默认为False。

Event.wait([timeout]) : 堵塞线程,直到Event对象内部标识位被设为True或超时(如果提供了参数timeout)。

Event.set() :将标识位设为Ture

Event.clear() : 将标识伴设为False。

Event.isSet() :判断标识位是否为Ture。

1 event2 importthreading3

4

5 def do(event): #定义一个函数,传递参数envent,其实就是传递了一个对象

6 print 'start'

7 event.wait() #True则不阻塞

8 print 'execute'

9

10

11 event_obj =threading.Event()12 for i in range(10):13 t = threading.Thread(target=do, args=(event_obj,)) #传递执行函数和参数

14 t.start()15

16 event_obj.clear() #将“Flag”设置为False

17 inp = raw_input('input:')18 if inp == 'true':19 event_obj.set() #set默认为True

event

queue模块

Queue 就是对队列,它是线程安全的

举例来说,我们去肯德基吃饭。厨房是给我们做饭的地方,前台负责把厨房做好的饭卖给顾客,顾客则去前台领取做好的饭。这里的前台就相当于我们的队列。

这个模型也叫生产者-消费者模型。

复制代码

import queue

q = queue.Queue(maxsize=0) # 构造一个先进显出队列,maxsize指定队列长度,为0 时,表示队列长度无限制。

q.join() # 等到队列为kong的时候,在执行别的操作

q.qsize() # 返回队列的大小 (不可靠)

q.empty() # 当队列为空的时候,返回True 否则返回False (不可靠)

q.full() # 当队列满的时候,返回True,否则返回False (不可靠)

q.put(item, block=True, timeout=None) # 将item放入Queue尾部,item必须存在,可以参数block默认为True,表示当队列满时,会等待队列给出可用位置,

为False时为非阻塞,此时如果队列已满,会引发queue.Full 异常。 可选参数timeout,表示 会阻塞设置的时间,过后,

如果队列无法给出放入item的位置,则引发 queue.Full 异常

q.get(block=True, timeout=None) # 移除并返回队列头部的一个值,可选参数block默认为True,表示获取值的时候,如果队列为空,则阻塞,为False时,不阻塞,

若此时队列为空,则引发 queue.Empty异常。 可选参数timeout,表示会阻塞设置的时候,过后,如果队列为空,则引发Empty异常。

q.put_nowait(item) # 等效于 put(item,block=False)

q.get_nowait() # 等效于 get(item,block=False)

生产者--消费者:

1 #!/usr/bin/env python

2 importQueue3 importthreading4

5

6 message = Queue.Queue(10)7

8

9 defproducer(i):10 whileTrue:11 message.put(i)12

13

14 defconsumer(i):15 whileTrue:16 msg =message.get()17

18

19 for i in range(12):20 t = threading.Thread(target=producer, args=(i,))21 t.start()22

23 for i in range(10):24 t = threading.Thread(target=consumer, args=(i,))25 t.start()

生产者消费者模型

线程池

1 importqueue2 importthreading3 importcontextlib4 importtime5

6 StopEvent =object()7

8

9 classThreadPool(object):10

11 def __init__(self, max_num):12 self.q =queue.Queue()13 self.max_num =max_num14

15 self.terminal =False16 self.generate_list =[]17 self.free_list =[]18

19 def run(self, func, args, callback=None):20 """

21 线程池执行一个任务22 :param func: 任务函数23 :param args: 任务函数所需参数24 :param callback: 任务执行失败或成功后执行的回调函数,回调函数有两个参数1、任务函数执行状态;2、任务函数返回值(默认为None,即:不执行回调函数)25 :return: 如果线程池已经终止,则返回True否则None26 """

27

28 if len(self.free_list) == 0 and len(self.generate_list) <29 self.generate_thread w="(func," args callback self.q.put>

33 defgenerate_thread(self):34 """

35 创建一个线程36 """

37 t = threading.Thread(target=self.call)38 t.start()39

40 @contextlib.contextmanager41 defworker_state(self, xxx, val):42 xxx.append(val)43 try:44 yield

45 finally:46 xxx.remove(val)47

48 defcall(self):49 """

50 循环去获取任务函数并执行任务函数51 """

52 current_thread =threading.currentThread53 self.generate_list.append(current_thread)54

55 event =self.q.get()56 while event !=StopEvent:57

58 func, arguments, callback =event59 try:60 result = func(*arguments)61 status =True62 exceptException as e:63 status =False64 result =e65

66 if callback is notNone:67 try:68 callback(status, result)69 exceptException as e:70 pass

71

72 if self.terminal: #False

73 event =StopEvent74 else:75 #self.free_list.append(current_thread)

76 #event = self.q.get()

77 #self.free_list.remove(current_thread)

78 with self.worker_state(self.free_list, current_thread):79 event =self.q.get()80 else:81 self.generate_list.remove(current_thread)82

83 defclose(self):84 num =len(self.generate_list)85 whilenum:86 self.q.put(StopEvent)87 num -= 1

88

89 #终止线程(清空队列)

90 defterminate(self):91

92 self.terminal =True93

94 whileself.generate_list:95 self.q.put(StopEvent)96 self.q.empty()97 importtime98

99 defwork(i):100 print(i,"----")101

102 pool = ThreadPool(10)103 for item in range(50):104 pool.run(func=work, args=(item,))105

106 pool.terminate()

完整版线程池

1 #!/usr/bin/env python

2 #-*- coding:utf-8 -*-

3 importqueue4 importthreading5 importcontextlib6 importtime7

8 StopEvent = object() #定义标记的意义在于任务结束后退出的标记

9

10

11 classThreadPool(object):12

13 def __init__(self, max_num):14 self.q = queue.Queue() #定义队列无限大

15 self.max_num = max_num #定义最大值

16

17 self.terminal = False #定义为false

18 self.generate_list = [] #多少个进程正在执行

19 self.free_list = [] #定义空闲列表--空闲线程 初始化各种属性

20

21 def run(self, func, args, callback=None):22 """

23 线程池执行一个任务24 :param func: 任务函数25 :param args: 任务函数所需参数26 :param callback: 任务执行失败或成功后执行的回调函数,回调函数有两个参数1、任务函数执行状态;2、任务函数返回值(默认为None,即:不执行回调函数)27 :return: 如果线程池已经终止,则返回True否则None28 """

29

30 if len(self.free_list) == 0 and len(self.generate_list) <31 self.generate_thread w="(func," args callback self.q.put>

35 defgenerate_thread(self):36 """

37 创建一个线程38 """

39 t = threading.Thread(target=self.call)#并执行call方法

40 t.start()41

42 defcall(self):43 """

44 循环去获取任务函数并执行任务函数45 """

46 current_thread = threading.currentThread #拿到当前线程

47 self.generate_list.append(current_thread) #添加到正在使用线程队列

48

49 event = self.q.get() #--这里是一个获取到的元组w=()....

50 while event !=StopEvent:51

52 func, arguments, callback = event #w= (func, args, callback)

53 try:54 result = func(*arguments) #执行任务 ret = aaa() --def aaa(): return 1

55 status =True56 except Exception as e: #如果我这个任务报错

57 status =False58 result =e59

60 if callback is not None: #这是一个返回值

61 try:62 callback(status, result)63 exceptException as e:64 pass

65

66 self.free_list.append(current_thread) #---记得看上下文代码,执行完任务,把这个线程放到空闲队列里面

67 event = self.q.get()#当前的状态应该是没任务,线程等待任务,不结束

68 self.free_list.remove(current_thread) #获取任务移除休息线程

69 else:70 if event =StopEvent:71 self.generate_list.remove(current_thread) #移除当前正在运行的线程,等他运行完

72

73 defclose(self):74 num =len(self.generate_list)75 whilenum:76 self.q.put(StopEvent)#77 num -= 1

78

79

80 importtime81

82 defwork(i):83 print(i)84

85 pool = ThreadPool(10) #定义最大线程为10个,实例化,并初始化

86 for item in range(50): #创建了50个任务

87 pool.run(func=work, args=(item,)) #执行work函数,args是传参

88

89 pool.close() #关闭线程池

理解注释版线程池

Python 进程

1 from multiprocessing importProcess2 importthreading3 importtime4

5 deffoo(i):6 print 'say hi',i7

8 for i in range(10):9 p = Process(target=foo,args=(i,))10 p.start()

注意:由于进程之间的数据需要各自持有一份,所以创建进程需要的非常大的开销。

multiprocessing模块

multiprocessing是python的多进程管理包,和threading.Thread类似。直接从侧面用subprocesses替换线程使用GIL的方式,由于这一点,multiprocessing模块可以让程序员在给定的机器上充分的利用CPU。

在multiprocessing中,通过创建Process对象生成进程,然后调用它的start()方法,

各种参数的意思:

注意:

start() 开始进程

setDaemon(True):守护进程:mutilprocess.setDaemon(True)

terminate():退出进程:最好使用 poison pill,强制的使用terminate()

is_alive(): 进程创建之后,可以使用multiprocessing对象的is_alive方法查看线程是否运行,为True则运行

join():阻塞当前进程,直到调用join方法的那个进程执行完,再继续执行当前进程。|  或者也可以理解为: 进程池中进程执行完毕后在关闭, 如果注释, 那么程序直接关闭

守护进程

守护进程就是不阻挡主程序退出,自己干自己的 mutilprocess.setDaemon(True)

就这句

等待守护进程退出,要加上join,join可以传入浮点数值,等待n久就不等了

importmultiprocessingimporttimeimportsysdefdaemon():

name=multiprocessing.current_process().nameprint 'Starting:', name

time.sleep(2)print 'Exiting :', namedefnon_daemon():

name=multiprocessing.current_process().nameprint 'Starting:', nameprint 'Exiting :', nameif __name__ == '__main__':

d= multiprocessing.Process(name='daemon',

target=daemon)

d.daemon=True

n= multiprocessing.Process(name='non-daemon',

target=non_daemon)

n.daemon=False

d.start()

n.start()

d.join(1)print 'd.is_alive()', d.is_alive()

n.join()

View Code

终止进程

最好使用 poison pill,强制的使用terminate()

注意 terminate之后要join,使其可以更新状态

importmultiprocessingimporttimedefslow_worker():print 'Starting worker'time.sleep(0.1)print 'Finished worker'

if __name__ == '__main__':

p= multiprocessing.Process(target=slow_worker)print 'BEFORE:', p, p.is_alive()

p.start()print 'DURING:', p, p.is_alive()

p.terminate()print 'TERMINATED:', p, p.is_alive()

p.join()print 'JOINED:', p, p.is_alive()

简单示例:

1 from multiprocessing importProcess2

3 deff(name):4 print('hello', name)5

6 if __name__ == '__main__':7 p = Process(target=f, args=('bob',))8 p.start()9 p.join()

join()方法的示例:

from multiprocessing importProcessimportos, time, randomdefr1(process_name):for i in range(5):print process_name, os.getpid() #打印出当前进程的id

time.sleep(random.random())defr2(process_name):for i in range(5):print process_name, os.getpid() #打印出当前进程的id

time.sleep(random.random())if __name__ == "__main__":print "main process run..."p1= Process(target=r1, args=('process_name1', ))

p2= Process(target=r2, args=('process_name2', ))

p1.start()

p2.start()#p1.join()

#p2.join()

print "main process runned all lines..."

进程数据共享

进程各自持有一份数据,默认无法共享数据

1 #!/usr/bin/env python

2 #coding:utf-8

3

4 from multiprocessing importProcess5 from multiprocessing importManager6

7 importtime8

9 li =[]10

11 deffoo(i):12 li.append(i)13 print 'say hi',li14

15 for i in range(10):16 p = Process(target=foo,args=(i,))17 p.start()18

19 print 'ending',li

进程间无数据共享

1 #方法一,Array

2 from multiprocessing importProcess,Array3 temp = Array('i', [11,22,33,44])4

5 defFoo(i):6 temp[i] = 100+i7 for item intemp:8 print i,'----->',item9

10 for i in range(2):11 p = Process(target=Foo,args=(i,))12 p.start()13

14 #方法二:manage.dict()共享数据

15 from multiprocessing importProcess,Manager16

17 manage =Manager()18 dic =manage.dict()19

20 defFoo(i):21 dic[i] = 100+i22 printdic.values()23

24 for i in range(2):25 p = Process(target=Foo,args=(i,))26 p.start()27 p.join()

1 'c': ctypes.c_char, 'u': ctypes.c_wchar,2 'b': ctypes.c_byte, 'B': ctypes.c_ubyte,3 'h': ctypes.c_short, 'H': ctypes.c_ushort,4 'i': ctypes.c_int, 'I': ctypes.c_uint,5 'l': ctypes.c_long, 'L': ctypes.c_ulong,6 'f': ctypes.c_float, 'd': ctypes.c_double

当创建进程时(非使用时),共享数据会被拿到子进程中,当进程中执行完毕后,再赋值给原值。

1 #!/usr/bin/env python

2 #-*- coding:utf-8 -*-

3

4 from multiprocessing importProcess, Array, RLock5

6 defFoo(lock,temp,i):7 """

8 将第0个数加1009 """

10 lock.acquire()11 temp[0] = 100+i12 for item intemp:13 print i,'----->',item14 lock.release()15

16 lock =RLock()17 temp = Array('i', [11, 22, 33, 44])18

19 for i in range(20):20 p = Process(target=Foo,args=(lock,temp,i,))21 p.start()

进程锁实例

进程池

进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止。

进程池中有两个方法:

apply

apply_async

1 #!/usr/bin/env python

2 #-*- coding:utf-8 -*-

3 from multiprocessing importProcess,Pool4 importtime5

6 defFoo(i):7 time.sleep(2)8 return i+100

9

10 defBar(arg):11 printarg12

13 pool = Pool(5) #进程池14 #print pool.apply(Foo,(1,))

15 #print pool.apply_async(func =Foo, args=(1,)).get()

16

17 for i in range(10):18 pool.apply_async(func=Foo, args=(i,),callback=Bar)#但它是非阻塞且支持结果返回进行回调 (回调 ret = pool.apply....)19

20 print 'end'

21 pool.close()#关闭进程池,不再接受新的进程

22 pool.join()#进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。

1 #apply和apply_async

2

3

4 from multiprocessing importPool5 importtime6

7 deff1(a):8 time.sleep(1)9 print(a)10 return 1000

11 deff2(arg):12 print(arg)13

14 if __name__ == '__main__':15 pool = Pool(5)16 for i in range(10):17 pool.apply_async(func=f1, args=(i,), callback=f2)18 #pool.apply(func=f1, args=(i,))

19 print('1111111')20

21 pool.close()22 pool.join()

window环境代码

协程

线程和进程的操作是由程序触发系统接口,最后的执行者是系统;协程的操作则是程序员。

协程存在的意义:对于多线程应用,CPU通过切片的方式来切换线程间的执行,线程切换时需要耗时(保存状态,下次继续)。协程,则只使用一个线程,在一个线程中规定某个代码块执行顺序。

协程的适用场景:当程序中存在大量不需要CPU的操作时(IO),适用于协程;

greenlet

1 #!/usr/bin/env python

2 #-*- coding:utf-8 -*-

3

4

5 from greenlet importgreenlet6

7

8 deftest1():9 print 12

10 gr2.switch()11 print 34

12 gr2.switch()13

14

15 deftest2():16 print 56

17 gr1.switch()18 print 78

19

20 gr1 =greenlet(test1)21 gr2 =greenlet(test2)22 gr1.switch()

gevent

1 importgevent2

3 deffoo():4 print('Running in foo')5 gevent.sleep(0)6 print('Explicit context switch to foo again')7

8 defbar():9 print('Explicit context to bar')10 gevent.sleep(0)11 print('Implicit context switch back to bar')12

13 gevent.joinall([14 gevent.spawn(foo),15 gevent.spawn(bar),16 ])

遇到IO操作自动切换:

1 from gevent importmonkey; monkey.patch_all()2 importgevent3 importurllib24

5 deff(url):6 print('GET: %s' %url)7 resp =urllib2.urlopen(url)8 data =resp.read()9 print('%d bytes received from %s.' %(len(data), url))10

11 gevent.joinall([12 gevent.spawn(f, 'https://www.python.org/'),13 gevent.spawn(f, 'https://www.yahoo.com/'),14 gevent.spawn(f, 'https://github.com/'),15 ])

View Code

31>29>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/488978.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

iOS事件的响应和传递机制

跟二狗子哥哥交流的时候&#xff0c;他总说我&#xff0c;说的过程太业余。故 好好学习整理一下。努力不那么业余。 一、事件的产生、传递、响应&#xff1a; 1、事件从父控件依次传递到子控件&#xff0c;寻找最合适的子控件View。 2、寻找最合适的View的底层实现&#xff0c;…

php 树状数组公式,PY个树状数组

树状数组比较简单&#xff0c;于是就挑它下手了...于是生活终于也对咱下手了...要讲的就两个东西&#xff0c;一个是开数组&#xff0c;全局变量写最前面&#xff0c;数组是这么开的&#xff1a; f[0 for i in range(500005)]另外一个就是 注意 split()还有一句就是咱发现 pyth…

三宝机器人怎么充电_巨人通力导致吉祥三宝+36号故障怪现象的又一因素

想必大家都有过这样的经历&#xff1a;在电梯故障频繁出现时&#xff0c;明明可以判断是哪里的问题&#xff0c;但事实却是让你感觉不可思议&#xff0c;并且排查过程颇为周折。今天和大家分享一下我经历的巨人通力GPS30K电梯出现的吉祥三宝故障的排查过程。下图为电梯控制柜铭…

《自然》展望2020年重大科学事件!中国有两个大计划安排上了

来源&#xff1a;科技日报图片来源&#xff1a;Nature官网&#xff08;不包括标注了来源的图片&#xff09;“千门万户曈曈日&#xff0c;总把新桃换旧符”&#xff01;在辞旧迎新之际&#xff0c;我们除了要埋头梳理过去一年的悲欢得失&#xff0c;也应抬头眺望新一年的星辰大…

discuz search.php修改,discuz程序如何将热门搜索修改为指向门户搜索的方法

站长朋友们使用discuz论坛程序建站&#xff0c;细心的站长朋友们发现首页右上角有个热门搜索功能。这个功能的主要作用就是可以让会员们第一时间搜索到本论坛内需要找到的帖子&#xff0c;这样做就给会员朋友们提供了很大的好处&#xff0c;不用再为了找到需要的帖子而大费周章…

vue aplayer 进度条无法拖动_Vue-rideo-player视频播放插件的使用

***** git项目地址&#xff1a; https://github.com/surmon-china/vue-video-player***** 参考文章&#xff1a; https://www.jianshu.com/p/532fc1d8c90c使用安装&#xff1a; npm install vue-video-player --save2. 在main.js入口文件中引入import VideoPlayer from vue-vid…

php流程控制作业题,php流程控制

一、get传值我们请求服务器下一步操作啊&#xff0c;都是用get进行传值&#xff0c;然后服务器用预定义变量数组$_GET&#xff0c;接受。二、流程控制1 三元运算符 ? :逻辑很简单&#xff0c;就是设置条件&#xff0c;条件成立就执行“&#xff1f;” 。条件不成立就执行”:…

JS中的call()和apply()方法(转)

转自&#xff1a;http://uule.iteye.com/blog/1158829 JS中的call()和apply()方法 博客分类&#xff1a; JS1、方法定义 call方法: 语法&#xff1a;call([thisObj[,arg1[, arg2[, [,.argN]]]]]) 定义&#xff1a;调用一个对象的一个方法&#xff0c;以另一个对象替换当前对象…

中国AI芯片产业发展白皮书:未来三年年均增长率超50%

来源&#xff1a;赛迪顾问《中国AI芯片产业发展白皮书》从AI芯片的定义及分类、发展过程与现状、应用机会、竞争格局、发展趋势等多角度全面剖析AI芯片的发展新态势、 技术演进及行业格局&#xff0c;旨在为业内相关企业把握行业发展动态、挖掘市场机遇&#xff0c;提供借鉴与参…

python队列怎么用_如何在Python中使用多处理队列? - python

我很难理解多处理队列如何在python上工作以及如何实现它。假设我有两个python模块&#xff0c;它们从共享文件中访问数据&#xff0c;我们将这两个模块称为writer和Reader。我的计划是让读取器和写入器都将请求放入两个单独的多处理队列中&#xff0c;然后让第三个进程将这些请…

php获取显示图书数据,php基于dom实现读取图书xml格式数据的方法

本文实例讲述了php基于dom实现读取图书xml格式数据的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;<?php $doc new DOMDocument();$doc->load( books.xml );$books $doc->getElementsByTagName( "book" );foreach( $books as $book ){$au…

codeforces problem 768B

这是第一篇博客&#xff1f;日志也行。。。codeforces problem 768B这个题做了很长时间--好几天吧&#xff0c;有空的时候就想怎么做。问题描述看 http://codeforces.com/problemset/problem/768/B看起来是个三叉树的题目。最开始我想用递归完成&#xff0c;遍历每一个节点&…

人工智能与经济生产力:期待进化,而不是革命

Illustration: Edmon de Haro来源&#xff1a; IEEE电气电子工程师尽管大肆宣传&#xff0c;人工智能仍需数年时间才能显著提高经济生产力。2016年&#xff0c;总部位于伦敦的Alphabet&#xff08;也是谷歌的母公司&#xff09;的子公司DeepMind Technologies报告称&#xff0c…

oracle 表 上限,Oracle分区表(Partition Table)的数量限制

Oracle分区表(Partition Table)的数量限制有朋友在我的留言板上问到这样一个问题:oracle分区表是不是有最大分区个数限制,我有一张大约20G的表,有好多分区(按时间),结果根据这个时间条件查询就报ORA-03113 end-of-file on communication channel错误,然后断开链接,硬件与网络都…

wpf 控件生成图片_EyeshotCAD控件生成以及作用

EyeshotCAD控件生成以及作用devDept Software是一家软件开发公司&#xff0c;成立于2006年&#xff0c;总部位于意大利博洛尼亚。 devDept Software是Microsoft .NET Framework的全球最大的CAD软件组件提供商。devDept SoftwareEyeshot的旗舰产品Eyeshot旨在满足CAD开发人员不断…

张恭庆院士:数学的意义(最全最牛的解释)

来源&#xff1a;数学严老师北京大学数学科学学院教授、中国科学院院士、第三世界科学院院士数学既是一种文化、一种“思想的体操”&#xff0c;更是现代理性文化的核心。马克思说&#xff1a;“一门科学只有当它达到了能够成功地运用数学时&#xff0c;才算真正发展了。”在前…

动态通过网络获取json来tabbar图片和文字或其他信息

动态通过网络获取json来tabbar图片和文字或其他信息转载于:https://www.cnblogs.com/TheYouth/p/6488843.html

oracle 根据分隔符提取,oracle使用指定分隔符导出数据到文件

最近有需求要导出一个专业的详单&#xff0c;用于倒入sqlserver系统&#xff0c;要求用分隔符隔开各字段。一开始准备用toad查询出来在save as&#xff0c;但发现表太多&#xff0c;要一张一张表盯着&#xff0c;而且由于详单数据量大&#xff0c;查询导出占用了大量的客户端内…

vue mxgraph渲染xml页面_Vue的两个版本

Vue.js分为两个版本&#xff0c;简单来说就是一个是完整版vue.js&#xff0c;一个是非完整版vue.runtime.js&#xff1a;1. HTML的书写位置不同完整版&#xff1a;完整版的HTML书写的位置有两个&#xff0c;一个是直接在 *.html 文件中使用 Vue 语法&#xff0c;如下所示&#…

美智库发布报告:《美国在人工智能时代的行动蓝图》

来源&#xff1a;新美国安全中心12月17日&#xff0c;新美国安全中心发布报告《美国人工智能世纪&#xff1a;行动蓝图》&#xff0c;指出先进计算、量子科学、人工智能、合成生物学、5G、增材制造等技术的快速进步正在改变技术运行机制&#xff0c;其中人工智能将产生最广泛的…