Python之路第一课Day9--随堂笔记之二(进程、线程、协程篇)

2023-10-17 18:50

本文主要是介绍Python之路第一课Day9--随堂笔记之二(进程、线程、协程篇),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本节内容

  1. 进程、与线程区别
  2. python GIL全局解释器锁
  3. 线程
    1. 语法
    2. join
    3. 线程锁之Lock\Rlock\信号量
    4. 将线程变为守护进程
    5. Event事件 
    6. queue队列
    7. 生产者消费者模型
    8. Queue队列
    9. 开发一个线程池
  4. 进程
    1. 语法
    2. 进程间通讯
    3. 进程池    

一、进程与线程

1.线程

  线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务

  A thread is an execution context, which is all the information a CPU needs to execute a stream of instructions.
  Suppose you're reading a book, and you want to take a break right now, but you want to be able to come back and resume reading from the exact point where you stopped. One way to achieve that is by jotting down the page number, line number, and word number. So your execution context for reading a book is these 3 numbers.
  If you have a roommate, and she's using the same technique, she can take the book while you're not using it, and resume reading from where she stopped. Then you can take it back, and resume it from where you were.
  Threads work in the same way. A CPU is giving you the illusion that it's doing multiple computations at the same time. It does that by spending a bit of time on each computation. It can do that because it has an execution context for each computation. Just like you can share a book with your friend, many tasks can share a CPU.
  On a more technical level, an execution context (therefore a thread) consists of the values of the CPU's registers.
  Last: threads are different from processes. A thread is a context of execution, while a process is a bunch of resources associated with a computation. A process can have one or many threads.
  Clarification: the resources associated with a process include memory pages (all the threads in a process have the same view of the memory), file descriptors (e.g., open sockets), and security credentials (e.g., the ID of the user who started the process).

2.进程

  An executing instance of a program is called a process.

  Each process provides the resources needed to execute a program. A process has a virtual address space, executable code, open handles to system objects, a security context, a unique process identifier, environment variables, a priority class, minimum and maximum working set sizes, and at least one thread of execution. Each process is started with a single thread, often called the primary thread, but can create additional threads from any of its threads.

3.线程进程区别:

  1. Threads share the address space of the process that created it; processes have their own address space.
  2. Threads have direct access to the data segment of its process; processes have their own copy of the data segment of the parent process.
  3. Threads can directly communicate with other threads of its process; processes must use interprocess communication to communicate with sibling processes.
  4. New threads are easily created; new processes require duplication of the parent process.
  5. Threads can exercise considerable control over threads of the same process; processes can only exercise control over child processes.
  6. Changes to the main thread (cancellation, priority change, etc.) may affect the behavior of the other threads of the process; changes to the parent process does not affect child processes.

3.python GIL

In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython’s memory management is not thread-safe. (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.)

上面的核心意思就是,无论你启多少个线程,你有多少个cpu, Python在执行的时候会淡定的在同一时刻只允许一个线程运行,擦。。。,那这还叫什么多线程呀?莫如此早的下结结论,听我现场讲。

  首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念。就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码。有名的编译器例如GCC,INTEL C++,Visual C++等。Python也一样,同样一段代码可以通过CPython,PyPy,Psyco等不同的Python执行环境来执行。像其中的JPython就没有GIL。然而因为CPython是大部分环境下默认的Python执行环境。所以在很多人的概念里CPython就是Python,也就想当然的把GIL归结为Python语言的缺陷。所以这里要先明确一点:GIL并不是Python的特性,Python完全可以不依赖于GIL

这篇文章透彻的剖析了GIL对python多线程的影响,强烈推荐看一下:

http://www.dabeaz.com/python/UnderstandingGIL.pdf 

二、python threading模块

调用方式:

a.直接调用

mport threading
import timedef sayhi(num): #定义每个线程要运行的函数print("running on number:%s" %num)time.sleep(3)if __name__ == '__main__':t1 = threading.Thread(target=sayhi,args=(1,)) #生成一个线程实例t2 = threading.Thread(target=sayhi,args=(2,)) #生成另一个线程实例
 t1.start() #启动线程t2.start() #启动另一个线程print(t1.getName()) #获取线程名print(t2.getName())

 

b.集成式调用

import threading,timeclass MyThread(threading.Thread):def __init__(self,num):threading.Thread.__init__(self)self.num = numdef run(self):#定义每个线程要运行的函数print("running on number:%s" %self.num)time.sleep(3)if __name__ == '__main__':t1 = MyThread(1)t2 = MyThread(2)t1.start()t2.start()

三、json & daemon

Some threads do background tasks, like sending keepalive packets, or performing periodic garbage collection, or whatever. These are only useful when the main program is running, and it's okay to kill them off once the other, non-daemon, threads have exited.
  Without daemon threads, you'd have to keep track of them, and tell them to exit, before your program can completely quit. By setting them as daemon threads, you can let them run and forget about them, and when your program quits, any daemon threads are killed automatically.

#_*_coding:utf-8_*_import time
import threadingdef run(n):print('[%s]------running----\n' % n)time.sleep(2)print('--done--')def main():for i in range(5):t = threading.Thread(target=run,args=[i,])t.start()t.join(1)print('starting thread', t.getName())m = threading.Thread(target=main,args=[])
m.setDaemon(True) #将main线程设置为Daemon线程,它做为程序主线程的守护线程,当主线程退出时,m线程也会退出,由m启动的其它子线程会同时退出,不管是否执行完任务
m.start()
m.join(timeout=2)
print("---main thread done----")
Note:Daemon threads are abruptly stopped at shutdown.
Their resources (such as open files, database transactions, etc.) may not be released properly.
If you want your threads to stop gracefully, make them non-daemonic and use a suitable signalling mechanism such as an Event.

四、线程锁(互斥锁Mutex)

  一个进程下可以启动多个线程,多个线程共享父进程的内存空间,也就意味着每个线程可以访问同一份数据,此时,如果2个线程同时要修改同一份数据,会出现什么状况?

import time
import threadingdef addNum():global num #在每个线程中都获取这个全局变量print('--get num:',num )time.sleep(1)num  -=1 #对此公共变量进行-1操作
 
num = 100  #设定一个共享变量
thread_list = []
for i in range(100):t = threading.Thread(target=addNum)t.start()thread_list.append(t)for t in thread_list: #等待所有线程执行完毕
    t.join()print('final num:', num )

正常来讲,这个num结果应该是0, 但在python 2.7上多运行几次,会发现,最后打印出来的num结果不总是0,为什么每次运行的结果不一样呢? 哈,很简单,假设你有A,B两个线程,此时都 要对num 进行减1操作, 由于2个线程是并发同时运行的,所以2个线程很有可能同时拿走了num=100这个初始变量交给cpu去运算,当A线程去处完的结果是99,但此时B线程运算完的结果也是99,两个线程同时CPU运算的结果再赋值给num变量后,结果就都是99。那怎么办呢? 很简单,每个线程在要修改公共数据时,为了避免自己在还没改完的时候别人也来修改此数据,可以给这个数据加一把锁, 这样其它线程想修改此数据时就必须等待你修改完毕并把锁释放掉后才能再访问此数据。 

*注:不要在3.x上运行,不知为什么,3.x上的结果总是正确的,可能是自动加了锁

加锁版本

import time
import threadingdef addNum():global num #在每个线程中都获取这个全局变量print('--get num:',num )time.sleep(1)lock.acquire() #修改数据前加锁num  -=1 #对此公共变量进行-1操作lock.release() #修改后释放
 
num = 100  #设定一个共享变量
thread_list = []
lock = threading.Lock() #生成全局锁
for i in range(100):t = threading.Thread(target=addNum)t.start()thread_list.append(t)for t in thread_list: #等待所有线程执行完毕
    t.join()print('final num:', num )

GIL VS Lock 

  机智的同学可能会问到这个问题,就是既然你之前说过了,Python已经有一个GIL来保证同一时间只能有一个线程来执行了,为什么这里还需要lock? 注意啦,这里的lock是用户级的lock,跟那个GIL没关系 ,具体我们通过下图来看一下+配合我现场讲给大家,就明白了。

RLock(递归锁)

说白了就是在一个大锁中还要再包含子锁

import threading,timedef run1():print("grab the first part data")lock.acquire()global numnum +=1lock.release()return num
def run2():print("grab the second part data")lock.acquire()global  num2num2+=1lock.release()return num2
def run3():lock.acquire()res = run1()print('--------between run1 and run2-----')res2 = run2()lock.release()print(res,res2)if __name__ == '__main__':num,num2 = 0,0lock = threading.RLock()for i in range(10):t = threading.Thread(target=run3)t.start()while threading.active_count() != 1:print(threading.active_count())
else:print('----all threads done---')print(num,num2)

Semaphore(信号量)

互斥锁 同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据 ,比如厕所有3个坑,那最多只允许3个人上厕所,后面的人只能等里面有人出来了才能再进去。

import threading,timedef run(n):semaphore.acquire()time.sleep(1)print("run the thread: %s\n" %n)semaphore.release()if __name__ == '__main__':num= 0semaphore  = threading.BoundedSemaphore(5) #最多允许5个线程同时运行for i in range(20):t = threading.Thread(target=run,args=(i,))t.start()while threading.active_count() != 1:pass #print threading.active_count()
else:print('----all threads done---')print(num)

Event

An event is a simple synchronization object;

the event represents an internal flag, and threads
can wait for the flag to be set, or set or clear the flag themselves.

event = threading.Event()

# a client thread can wait for the flag to be set

event.wait()

# a server thread can set or reset it

event.set()
event.clear()

If the flag is set, the wait method doesn’t do anything.
If the flag is cleared, wait will block until it becomes set again.
Any number of threads may wait for the same event.

通过Event来实现两个或多个线程间的交互,下面是一个红绿灯的例子,即起动一个线程做交通指挥灯,生成几个线程做车辆,车辆行驶按红灯停,绿灯行的规则。

#!/usr/bin/python
# -*- conding:utf-8 -*-
__Author__ = "YoungCheung"import time,threadingevent=threading.Event()
def lighter():count  = 0event.set()while True:if count >4 and count <10: #改成红灯event.clear() #清空标志位print("\033[41;1mred light is on ...\033[0m")elif count >10:event.set() #变绿灯count = 0else:print("\033[42;1mgreen light is on ...\033[0m")time.sleep(1)count +=1
def  car(name):while True:if event.is_set():print("[%s] running ..."% name)time.sleep(1)else:print("[%s] sees red light ,warting...." %name)event.wait()print("\033[34;1m[%s] green light is on ,start going...\033[0m" %name)light = threading.Thread(target=lighter,)
light.start()car1=threading.Thread(target=car,args=("tesla",))
car2=threading.Thread(target=car,args=("baoma730",))
car1.start()
car2.start()

  这里还有一个event使用的例子,员工进公司门要刷卡, 我们这里设置一个线程是“门”, 再设置几个线程为“员工”,员工看到门没打开,就刷卡,刷完卡,门开了,员工就可以通过。

#_*_coding:utf-8_*_
__author__ = 'Alex Li'
import threading
import time
import randomdef door():door_open_time_counter = 0while True:if door_swiping_event.is_set():print("\033[32;1mdoor opening....\033[0m")door_open_time_counter +=1else:print("\033[31;1mdoor closed...., swipe to open.\033[0m")door_open_time_counter = 0 #清空计时器
            door_swiping_event.wait()if door_open_time_counter > 3:#门开了已经3s了,该关了
            door_swiping_event.clear()time.sleep(0.5)def staff(n):print("staff [%s] is comming..." % n )while True:if door_swiping_event.is_set():print("\033[34;1mdoor is opened, passing.....\033[0m")breakelse:print("staff [%s] sees door got closed, swipping the card....." % n)print(door_swiping_event.set())door_swiping_event.set()print("after set ",door_swiping_event.set())time.sleep(0.5)
door_swiping_event  = threading.Event() #设置事件
door_thread = threading.Thread(target=door)
door_thread.start()for i in range(5):p = threading.Thread(target=staff,args=(i,))time.sleep(random.randrange(3))p.start()
View Code

五、queue队列

queue is especially useful in threaded programming when information must be exchanged safely between multiple threads.

class queue.Queue(maxsize=0) #先入先出
class queue.LifoQueue(maxsize=0) #last in fisrt out  class queue.PriorityQueue(maxsize=0) #存储数据时可设置优先级的队列

Constructor for a priority queue. maxsize is an integer that sets the upperbound limit on the number of items that can be placed in the queue. Insertion will block once this size has been reached, until queue items are consumed. If maxsize is less than or equal to zero, the queue size is infinite.

The lowest valued entries are retrieved first (the lowest valued entry is the one returned by sorted(list(entries))[0]). A typical pattern for entries is a tuple in the form: (priority_number, data).

exception queue.Empty

Exception raised when non-blocking get() (or get_nowait()) is called on a Queue object which is empty.

exception queue.Full

Exception raised when non-blocking put() (or put_nowait()) is called on a Queue object which is full.

Queue. qsize ()
Queue. empty () #return True if empty  
Queue. full () # return True if full 
Queue. put (itemblock=Truetimeout=None)

Put item into the queue. If optional args block is true and timeout is None (the default), block if necessary until a free slot is available. If timeout is a positive number, it blocks at most timeout seconds and raises the Full exception if no free slot was available within that time. Otherwise (block is false), put an item on the queue if a free slot is immediately available, else raise the Full exception (timeout is ignored in that case).

Queue. put_nowait (item)

Equivalent to put(item, False).

Queue. get (block=Truetimeout=None)

Remove and return an item from the queue. If optional args block is true and timeout is None (the default), block if necessary until an item is available. If timeout is a positive number, it blocks at most timeout seconds and raises the Empty exception if no item was available within that time. Otherwise (block is false), return an item if one is immediately available, else raise the Empty exception (timeout is ignored in that case).

Queue. get_nowait ()

Equivalent to get(False).

Two methods are offered to support tracking whether enqueued tasks have been fully processed by daemon consumer threads.

Queue. task_done ()

Indicate that a formerly enqueued task is complete. Used by queue consumer threads. For each get() used to fetch a task, a subsequent call to task_done() tells the queue that the processing on the task is complete.

If a join() is currently blocking, it will resume when all items have been processed (meaning that a task_done() call was received for every item that had been put() into the queue).

Raises a ValueError if called more times than there were items placed in the queue.

Queue. join () block直到queue被消费完毕

六、生产者消费者模型

 

在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。

为什么要使用生产者和消费者模式

在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。

什么是生产者消费者模式

生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。

下面来学习一个最基本的生产者消费者模型的例子

import threading
import queuedef producer():for i in range(10):q.put("骨头 %s" % i )print("开始等待所有的骨头被取走...")q.join()print("所有的骨头被取完了...")def consumer(n):while q.qsize() >0:print("%s 取到" %n  , q.get())q.task_done() #告知这个任务执行完了
q = queue.Queue()p = threading.Thread(target=producer,)
p.start()c1 = consumer("陈荣华")

包子案例

import time,random
import queue,threading
q = queue.Queue()
def Producer(name):count = 0while count <20:time.sleep(random.randrange(3))q.put(count)print('Producer %s has produced %s baozi..' %(name, count))count +=1
def Consumer(name):count = 0while count <20:time.sleep(random.randrange(4))if not q.empty():data = q.get()print(data)print('\033[32;1mConsumer %s has eat %s baozi...\033[0m' %(name, data))else:print("-----no baozi anymore----")count +=1
p1 = threading.Thread(target=Producer, args=('A',))
c1 = threading.Thread(target=Consumer, args=('B',))
p1.start()
c1.start()

多进程multiprocessing

multiprocessing is a package that supports spawning processes using an API similar to the threading module. The multiprocessing package offers both local and remote concurrency,effectively side-stepping the Global Interpreter Lock by using subprocesses instead of threads. Due to this, the multiprocessing module allows the programmer to fully leverage multiple processors on a given machine. It runs on both Unix and Windows.

from multiprocessing import Process
import time
def f(name):time.sleep(2)print('hello', name)if __name__ == '__main__':p = Process(target=f, args=('bob',))p.start()p.join()

To show the individual process IDs involved, here is an expanded example:

from multiprocessing import Process
import osdef info(title):print(title)print('module name:', __name__)print('parent process:', os.getppid())print('process id:', os.getpid())print("\n\n")def f(name):info('\033[31;1mfunction f\033[0m')print('hello', name)if __name__ == '__main__':info('\033[32;1mmain process line\033[0m')p = Process(target=f, args=('bob',))p.start()p.join()

example:

#!/usr/bin/python
# -*- conding:utf-8 -*-
__Author__ = "YoungCheung"
import multiprocessing
import time,threading
def thread_run():print(threading.get_ident())
def run(name):time.sleep(2)print('hello',name)t = threading.Thread(target=thread_run,)t.start()
if __name__ ==  '__main__':for i in range(10):p=multiprocessing.Process(target=run,args=('zy %s' %i,))p.start()

结果:

hello  zy 2
26384..........
hello  zy 8
25792
hello  zy 1
25772
hello  zy 5
25860
hello  zy 9
2532

进程间通讯 

不同进程间内存是不共享的,要想实现两个进程间的数据交换,可以用以下方法:

Queues

使用方法跟threading里的queue差不多

#!/usr/bin/python
# -*- conding:utf-8 -*-
__Author__ = "YoungCheung"
from multiprocessing import Process, Queue
def f(qq):qq.put([42, None, 'hello'])
if __name__ == '__main__':q = Queue()p = Process(target=f, args=(q,))p.start()print(q.get())    # prints "[42, None, 'hello']"p.join()

Pipes

The Pipe() function returns a pair of connection objects connected by a pipe which by default is duplex (two-way). For example:

#!/usr/bin/python
# -*- conding:utf-8 -*-
__Author__ = "YoungCheung"
from multiprocessing import Process, Pipe
def f(conn):conn.send(['hello ! -----msg from child'])print("from parent:",conn.recv())conn.close()
if __name__ == '__main__':parent_conn, child_conn = Pipe()p = Process(target=f, args=(child_conn,))p.start()print(parent_conn.recv())  # prints "[42, None, 'hello']"parent_conn.send("hello my son --msg from parent") # prints "[42, None, 'hello']"p.join()

The two connection objects returned by Pipe() represent the two ends of the pipe. Each connection object has send() and recv() methods (among others). Note that data in a pipe may become corrupted if two processes (or threads) try to read from or write to the same end of the pipe at the same time. Of course there is no risk of corruption from processes using different ends of the pipe at the same time.

 

Managers

  A manager object returned by Manager() controls a server process which holds Python objects and allows other processes to manipulate them using proxies.

A manager returned by Manager() will support types listdictNamespaceLockRLockSemaphoreBoundedSemaphoreConditionEventBarrierQueueValue and Array. For example,

#!/usr/bin/python
# -*- conding:utf-8 -*-
__Author__ = "YoungCheung"
from multiprocessing import Process, Manager
import os
def f(d, l):# d[1] = '1'# d['2'] = 2# d[0.25] = Noned[os.getpid()]= os.getpid()l.append(os.getpid())print(l)
if __name__ == '__main__':with Manager() as manager:d = manager.dict() #生成一个字典,可在多进程间共享传递l = manager.list(range(5)) #生成一个列表,可在多进程间共享传递p_list = []for i in range(10):p = Process(target=f,args=(d, l))p.start()p_list.append(p)for res in p_list: #等待结果
            res.join()print(d)print(l)

输出结果:

[0, 1, 2, 3, 4, 56620]
[0, 1, 2, 3, 4, 56620, 57936]
[0, 1, 2, 3, 4, 56620, 57936, 58336]
[0, 1, 2, 3, 4, 56620, 57936, 58336, 54620]
[0, 1, 2, 3, 4, 56620, 57936, 58336, 54620, 57660]
[0, 1, 2, 3, 4, 56620, 57936, 58336, 54620, 57660, 48364]
[0, 1, 2, 3, 4, 56620, 57936, 58336, 54620, 57660, 48364, 56636]
[0, 1, 2, 3, 4, 56620, 57936, 58336, 54620, 57660, 48364, 56636, 58340]
[0, 1, 2, 3, 4, 56620, 57936, 58336, 54620, 57660, 48364, 56636, 58340, 20836]
[0, 1, 2, 3, 4, 56620, 57936, 58336, 54620, 57660, 48364, 56636, 58340, 20836, 57388]
{57936: 57936, 58336: 58336, 20836: 20836, 58340: 58340, 48364: 48364, 57660: 57660, 54620: 54620, 56636: 56636, 56620: 56620, 57388: 57388}
[0, 1, 2, 3, 4, 56620, 57936, 58336, 54620, 57660, 48364, 56636, 58340, 20836, 57388]

进程同步

Without using the lock output from the different processes is liable to get all mixed up.

#!/usr/bin/python
# -*- conding:utf-8 -*-
__Author__ = "YoungCheung"
from multiprocessing import Process, Lock
def f(l, i): #l = lock i = args
    l.acquire()try:print('hello world', i)finally:l.release()
if __name__ == '__main__':lock = Lock()for num in range(10):Process(target=f, args=(lock, num)).start()

进程池  

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

进程池中有两个方法:

  • apply
  • apply_async
#!/usr/bin/python
# -*- conding:utf-8 -*-
__Author__ = "YoungCheung"
from  multiprocessing import Process,Pool,freeze_support
import time,os
def Foo(i):time.sleep(2)print("in process",os.getpid())return i+100
def Bar(arg):print('-->执行完毕停止:',arg,os.getpid())
if __name__ == '__main__':#freeze_support()pool = Pool(processes=5) #允许进程池同时放入5个进程print("主进程:",os.getpid())for i in range(10):pool.apply_async(func=Foo, args=(i,),callback=Bar) #callback 回调# pool.apply_async(func=Foo, args=(i,)) #并行# pool.apply(func=Foo, args=(i,)) #串行print('主进程结束!')pool.close()pool.join()  #进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。

 

转载于:https://www.cnblogs.com/youngcheung/p/5880065.html

这篇关于Python之路第一课Day9--随堂笔记之二(进程、线程、协程篇)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/227279

相关文章

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

nudepy,一个有趣的 Python 库!

更多资料获取 📚 个人网站:ipengtao.com 大家好,今天为大家分享一个有趣的 Python 库 - nudepy。 Github地址:https://github.com/hhatto/nude.py 在图像处理和计算机视觉应用中,检测图像中的不适当内容(例如裸露图像)是一个重要的任务。nudepy 是一个基于 Python 的库,专门用于检测图像中的不适当内容。该

[Linux]:进程(下)

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:Linux学习 贝蒂的主页:Betty’s blog 1. 进程终止 1.1 进程退出的场景 进程退出只有以下三种情况: 代码运行完毕,结果正确。代码运行完毕,结果不正确。代码异常终止(进程崩溃)。 1.2 进程退出码 在编程中,我们通常认为main函数是代码的入口,但实际上它只是用户级

pip-tools:打造可重复、可控的 Python 开发环境,解决依赖关系,让代码更稳定

在 Python 开发中,管理依赖关系是一项繁琐且容易出错的任务。手动更新依赖版本、处理冲突、确保一致性等等,都可能让开发者感到头疼。而 pip-tools 为开发者提供了一套稳定可靠的解决方案。 什么是 pip-tools? pip-tools 是一组命令行工具,旨在简化 Python 依赖关系的管理,确保项目环境的稳定性和可重复性。它主要包含两个核心工具:pip-compile 和 pip

如何编写Linux PCIe设备驱动器 之二

如何编写Linux PCIe设备驱动器 之二 功能(capability)集功能(capability)APIs通过pci_bus_read_config完成功能存取功能APIs参数pos常量值PCI功能结构 PCI功能IDMSI功能电源功率管理功能 功能(capability)集 功能(capability)APIs int pcie_capability_read_wo

HTML提交表单给python

python 代码 from flask import Flask, request, render_template, redirect, url_forapp = Flask(__name__)@app.route('/')def form():# 渲染表单页面return render_template('./index.html')@app.route('/submit_form',