并發編程(多進程1)

一 multiprocessing模塊介紹

? ? python中的多線程無法利用多核優勢,如果想要充分地使用多核CPU的資源(os.cpu_count()查看),在python中大部分情況需要使用多進程。Python提供了multiprocessing。
? ? multiprocessing模塊用來開啟子進程,并在子進程中執行我們定制的任務(比如函數),該模塊與多線程模塊threading的編程接口類似。

 ?multiprocessing模塊的功能眾多:支持子進程、通信和共享數據、執行不同形式的同步,提供了Process、Queue、Pipe、Lock等組件。

? ? 需要再次強調的一點是:與線程不同,進程沒有任何共享狀態,進程修改的數據,改動僅限于該進程內。

二 Process類的介紹

? ??創建進程的類

復制代碼
Process([group [, target [, name [, args [, kwargs]]]]]),由該類實例化得到的對象,表示一個子進程中的任務(尚未啟動)強調:
1. 需要使用關鍵字的方式來指定參數
2. args指定的為傳給target函數的位置參數,是一個元組形式,必須有逗號
復制代碼

? ??參數介紹:

復制代碼
1 group參數未使用,值始終為None
2 
3 target表示調用對象,即子進程要執行的任務
4 
5 args表示調用對象的位置參數元組,args=(1,2,'egon',)
6 
7 kwargs表示調用對象的字典,kwargs={'name':'egon','age':18}
8 
9 name為子進程的名稱
復制代碼

 ?方法介紹:

復制代碼
 1 p.start():啟動進程,并調用該子進程中的p.run() 2 p.run():進程啟動時運行的方法,正是它去調用target指定的函數,我們自定義類的類中一定要實現該方法  3 4 p.terminate():強制終止進程p,不會進行任何清理操作,如果p創建了子進程,該子進程就成了僵尸進程,使用該方法需要特別小心這種情況。如果p還保存了一個鎖那么也將不會被釋放,進而導致死鎖5 p.is_alive():如果p仍然運行,返回True6 7 p.join([timeout]):主線程等待p終止(強調:是主線程處于等的狀態,而p是處于運行的狀態)。timeout是可選的超時時間,需要強調的是,p.join只能join住start開啟的進程,而不能join住run開啟的進程  
復制代碼

? ??屬性介紹:

復制代碼
1 p.daemon:默認值為False,如果設為True,代表p為后臺運行的守護進程,當p的父進程終止時,p也隨之終止,并且設定為True后,p不能創建自己的新進程,必須在p.start()之前設置
2 
3 p.name:進程的名稱
4 
5 p.pid:進程的pid
6 
7 p.exitcode:進程在運行時為None、如果為–N,表示被信號N結束(了解即可)
8 
9 p.authkey:進程的身份驗證鍵,默認是由os.urandom()隨機生成的32字符的字符串。這個鍵的用途是為涉及網絡連接的底層進程間通信提供安全性,這類連接只有在具有相同的身份驗證鍵時才能成功(了解即可)
復制代碼

三 Process類的使用

注意:在windows中Process()必須放到# if __name__ == '__main__':下

Since Windows has no fork, the multiprocessing module starts a new Python process and imports the calling module.
If Process() gets called upon import, then this sets off an infinite succession of new processes (or until your machine runs out of resources).
This is the reason for hiding calls to Process() inside

if __name__ == "__main__"
since statements inside this if-statement will not get called upon import.
由于Windows沒有fork,多處理模塊啟動一個新的Python進程并導入調用模塊。
如果在導入時調用Process(),那么這將啟動無限繼承的新進程(或直到機器耗盡資源)。
這是隱藏對Process()內部調用的原,使用if __name__ == “__main __”,這個if語句中的語句將不會在導入時被調用。

詳細解釋

3.1創建開啟子進程的兩種方式

from multiprocessing import Process
import time
def task(name):
??? print('%s is runing' %(name))
??? time.sleep(3)
??? print('%s is done' % (name))


if __name__ == '__main__':
??? p = Process(target=task,args=('太白金星',))
??? # p = Process(target=task,kwargs={'name':'太白金星'})? 兩種傳參方式
??? p.start()
??? print('====主')
from multiprocessing import Process
import time
# 方式二:

class MyProcess(Process):
??? def __init__(self,name):
???????
??????? self.name = name
??????? super().__init__()
???????
??? def run(self):? # 必須定義一個run方法
??????? print('%s is runing' % (self.name))
??????? time.sleep(3)
??????? print('%s is done' % (self.name))
???
???
if __name__ == '__main__':
??? p = MyProcess('太白金星')
??? p.start()
??? print('===主')

3.2驗證進程之間的空間隔離

# 接下來我們驗證一下進程之間的互相隔離。

# 在一個進程中
x = 1000
#
# def task():
#???? global x
#???? x = 2
#
# task()
# print(x)
# 在不同的進程中:
# from multiprocessing import Process
# import time
# x = 1000
#
# def task():
#???? global x
#???? x = 2
#
# if __name__ == '__main__':
#???? p = Process(target=task)
#???? p.start()
#???? time.sleep(3)
#???? print(x)

3.3 進程對象的join方法

from multiprocessing import Process
import time# 父進程等待子進程結束之后在執行
# 方法一 加sleep 不可取!# def task(n):
#     time.sleep(3)
#     print('子進程結束....')
#
# if __name__ == '__main__':
#     p = Process(target=task,args=('太白金星',))
#     p.start()
#     time.sleep(5)
#     print('主進程開始運行....')
#
# 這樣雖然達到了目的,
# 1,但是你在程序中故意加sleep極大影響程序的效率。
# 2,sleep(3)只是虛擬子進程運行的時間,子進程運行完畢的時間是不固定的。# 方法二: join# from multiprocessing import Process
# import time
#
#
# def task(n):
#     time.sleep(3)
#     print('子進程結束....')
#
#
# if __name__ == '__main__':
#     p = Process(target=task,args=('太白金星',))
#     p.start()
#     p.join()  # 等待p這個子進程運行結束之后,在執行下面的代碼(主進程).
#     print('主進程開始運行....')
#
# 接下來我要開啟十個子進程,先看看效果# from multiprocessing import Process
# import time
#
# def task(n):
#     print('%s is running' %n)
#
# if __name__ == '__main__':
#     for i in range(1, 11):
#         p = Process(target=task,args=(i,))
#         p.start()
#         '''
#         我這里是不是運行十個子進程之后,才會運行主進程?當然不會!!!
#         1,p.start()只是向操作系統發送一個請求而已,剩下的操作系統在內存開啟進程空間,運行進程程序不一定是馬上執行。
#         2,開啟進程的開銷是比較大的。
#         '''
#     print('主進程開始運行....')# 那么有人說,老師我對這個不理解,我給你拆解開來。# from multiprocessing import Process
# import time
#
# def task(n):
#     print('%s is running' %n)
#
# if __name__ == '__main__':
#     p1 = Process(target=task,args=(1,))
#     p2 = Process(target=task,args=(2,))
#     p3 = Process(target=task,args=(3,))
#     p4 = Process(target=task,args=(4,))
#     p5 = Process(target=task,args=(5,))
#
#     p1.start()
#     p2.start()
#     p3.start()
#     p4.start()
#     p5.start()
#
#     print('主進程開始運行....')# 接下來 實現起多子個進程,然后等待這些子進程都結束之后,在開啟主進程。# from multiprocessing import Process
# import time
#
# def task(n):
#     time.sleep(3)
#     print('%s is running' %n)
#
# if __name__ == '__main__':
#     start_time = time.time()
#     p1 = Process(target=task,args=(1,))
#     p2 = Process(target=task,args=(2,))
#     p3 = Process(target=task,args=(3,))
#     # 幾乎同一個時刻發送三個請求
#     p1.start()
#     p2.start()
#     p3.start()
#     # 對著三個自己成使用三個join
#
#     p1.join()
#     p2.join()
#     p3.join()
#
#     print(time.time() - start_time,'主進程開始運行....')
#     # 3s 多一點點這是來回切換的所用時間。# 那么在進行舉例:# from multiprocessing import Process
# import time
#
# def task(n):
#     time.sleep(n)
#     print('%s is running' %n)
#
# if __name__ == '__main__':
#     start_time = time.time()
#     p1 = Process(target=task,args=(1,))
#     p2 = Process(target=task,args=(2,))
#     p3 = Process(target=task,args=(3,))
#     # 幾乎同一個時刻發送三個請求
#     p1.start()
#     p2.start()
#     p3.start()
#     # 對著三個自己成使用三個join
#
#     p1.join()  # 1s
#     p2.join()  # 2s
#     p3.join()  # 3s
#
#     print(time.time() - start_time,'主進程開始運行....')# 3s 多一點點這是來回切換的所用時間。# 利用for循環精簡上面的示例:# from multiprocessing import Process
# import time
#
# def task(n):
#     time.sleep(1)
#     print('%s is running' %n)
#
# if __name__ == '__main__':
#     start_time = time.time()
#     # for i in range(1,4):
#     #     p = Process(target=task,args=(i,))
#     #     p.start()
#     #     p.join()
#
#     p1 = Process(target=task,args=(1,))
#     p2 = Process(target=task,args=(2,))
#     p3 = Process(target=task,args=(3,))
#     # 幾乎同一個時刻發送三個請求
#     p1.start()
#     p1.join()
#     p2.start()
#     p2.join()
#     p3.start()
#     p3.join()
#     # 上面的代碼,p1.join()他的作用:你的主進程代碼必須等我的p1子進程執行完畢之后,在執行
#     # p2.start()這個命令是主進程的代碼。
#     # 而 如果你這樣寫:
#     '''
#     p1.join()
#     p2.join()
#     p3.join()
#     '''
#
#     print(time.time() - start_time,'主進程開始運行....')# 所以你上面的代碼應該怎么寫?# from multiprocessing import Process
# import time
#
# def task(n):
#     time.sleep(3)
#     print('%s is running' %n)
#
# if __name__ == '__main__':
#     p_l = []
#     start_time = time.time()
#     for i in range(1,4):
#         p = Process(target=task,args=(i,))
#         p.start()
#         p_l.append(p)
#     # 對著三個自己成使用三個join
#     for i in p_l:
#         i.join()
#     print(time.time() - start_time,'主進程開始運行....')
復制代碼

3.4 進程對象的其他屬性(了解)

# from multiprocessing import Process
# import time
# import os
#
# def task(n):
#???? time.sleep(3)
#???? print('%s is running' %n,os.getpid(),os.getppid())
#
# if __name__ == '__main__':
#???? p1 = Process(target=task,args=(1,),name = '任務1')
#???? # print(p1.name) # 給子進程起名字
#???? # for i in range(3):
#???? #???? p = Process(target=task, args=(1,))
#???? #???? print(p.name)? # 給子進程起名字
#???? p1.start()
#???? # p1.terminate()
#???? # time.sleep(2)? # 睡一會,他就將我的子進程殺死了。
#???? # print(p1.is_alive())? # False
#???? print(p1.pid)
#???? # print('主')
#???? print(os.getpid())

3.5 僵尸進程與孤兒進程

一:僵尸進程(有害)
  僵尸進程:一個進程使用fork創建子進程,如果子進程退出,而父進程并沒有調用wait或waitpid獲取子進程的狀態信息,那么子進程的進程描述符仍然保存在系統中。這種進程稱之為僵死進程。詳解如下

我們知道在unix/linux中,正常情況下子進程是通過父進程創建的,子進程在創建新的進程。子進程的結束和父進程的運行是一個異步過程,即父進程永遠無法預測子進程到底什么時候結束,如果子進程一結束就立刻回收其全部資源,那么在父進程內將無法獲取子進程的狀態信息。

因此,UNⅨ提供了一種機制可以保證父進程可以在任意時刻獲取子進程結束時的狀態信息:
1、在每個進程退出的時候,內核釋放該進程所有的資源,包括打開的文件,占用的內存等。但是仍然為其保留一定的信息(包括進程號the process ID,退出狀態the termination status of the process,運行時間the amount of CPU time taken by the process等)
2、直到父進程通過wait / waitpid來取時才釋放. 但這樣就導致了問題,如果進程不調用wait / waitpid的話,那么保留的那段信息就不會釋放,其進程號就會一直被占用,但是系統所能使用的進程號是有限的,如果大量的產生僵死進程,將因為沒有可用的進程號而導致系統不能產生新的進程. 此即為僵尸進程的危害,應當避免。

  任何一個子進程(init除外)在exit()之后,并非馬上就消失掉,而是留下一個稱為僵尸進程(Zombie)的數據結構,等待父進程處理。這是每個子進程在結束時都要經過的階段。如果子進程在exit()之后,父進程沒有來得及處理,這時用ps命令就能看到子進程的狀態是“Z”。如果父進程能及時 處理,可能用ps命令就來不及看到子進程的僵尸狀態,但這并不等于子進程不經過僵尸狀態。? 如果父進程在子進程結束之前退出,則子進程將由init接管。init將會以父進程的身份對僵尸狀態的子進程進行處理。

二:孤兒進程(無害)

  孤兒進程:一個父進程退出,而它的一個或多個子進程還在運行,那么那些子進程將成為孤兒進程。孤兒進程將被init進程(進程號為1)所收養,并由init進程對它們完成狀態收集工作。

  孤兒進程是沒有父進程的進程,孤兒進程這個重任就落到了init進程身上,init進程就好像是一個民政局,專門負責處理孤兒進程的善后工作。每當出現一個孤兒進程的時候,內核就把孤 兒進程的父進程設置為init,而init進程會循環地wait()它的已經退出的子進程。這樣,當一個孤兒進程凄涼地結束了其生命周期的時候,init進程就會代表黨和政府出面處理它的一切善后工作。因此孤兒進程并不會有什么危害。

我們來測試一下(創建完子進程后,主進程所在的這個腳本就退出了,當父進程先于子進程結束時,子進程會被init收養,成為孤兒進程,而非僵尸進程),文件內容

import os
import sys
import time

pid = os.getpid()
ppid = os.getppid()
print 'im father', 'pid', pid, 'ppid', ppid
pid = os.fork()
#執行pid=os.fork()則會生成一個子進程
#返回值pid有兩種值:
#??? 如果返回的pid值為0,表示在子進程當中
#??? 如果返回的pid值>0,表示在父進程當中
if pid > 0:
??? print 'father died..'
??? sys.exit(0)

# 保證主線程退出完畢
time.sleep(1)
print 'im child', os.getpid(), os.getppid()

執行文件,輸出結果:
im father pid 32515 ppid 32015
father died..
im child 32516 1

看,子進程已經被pid為1的init進程接收了,所以僵尸進程在這種情況下是不存在的,存在只有孤兒進程而已,孤兒進程聲明周期結束自然會被init來銷毀。


三:僵尸進程危害場景:

  例如有個進程,它定期的產 生一個子進程,這個子進程需要做的事情很少,做完它該做的事情之后就退出了,因此這個子進程的生命周期很短,但是,父進程只管生成新的子進程,至于子進程 退出之后的事情,則一概不聞不問,這樣,系統運行上一段時間之后,系統中就會存在很多的僵死進程,倘若用ps命令查看的話,就會看到很多狀態為Z的進程。 嚴格地來說,僵死進程并不是問題的根源,罪魁禍首是產生出大量僵死進程的那個父進程。因此,當我們尋求如何消滅系統中大量的僵死進程時,答案就是把產生大 量僵死進程的那個元兇槍斃掉(也就是通過kill發送SIGTERM或者SIGKILL信號啦)。槍斃了元兇進程之后,它產生的僵死進程就變成了孤兒進 程,這些孤兒進程會被init進程接管,init進程會wait()這些孤兒進程,釋放它們占用的系統進程表中的資源,這樣,這些已經僵死的孤兒進程 就能瞑目而去了。

四:測試
#1、產生僵尸進程的程序test.py內容如下

#coding:utf-8
from multiprocessing import Process
import time,os

def run():
??? print('子',os.getpid())

if __name__ == '__main__':
??? p=Process(target=run)
??? p.start()
???
??? print('主',os.getpid())
??? time.sleep(1000)


#2、在unix或linux系統上執行
[root@vm172-31-0-19 ~]# python3? test.py &
[1] 18652
[root@vm172-31-0-19 ~]# 主 18652
子 18653

[root@vm172-31-0-19 ~]# ps aux |grep Z
USER?????? PID %CPU %MEM??? VSZ?? RSS TTY????? STAT START?? TIME COMMAND
root???? 18653? 0.0? 0.0????? 0???? 0 pts/0??? Z??? 20:02?? 0:00 [python3] <defunct> #出現僵尸進程
root???? 18656? 0.0? 0.0 112648?? 952 pts/0??? S+?? 20:02?? 0:00 grep --color=auto Z

[root@vm172-31-0-19 ~]# top #執行top命令發現1zombie
top - 20:03:42 up 31 min,? 3 users,? load average: 0.01, 0.06, 0.12
Tasks:? 93 total,?? 2 running,? 90 sleeping,?? 0 stopped,?? 1 zombie
%Cpu(s):? 0.0 us,? 0.3 sy,? 0.0 ni, 99.7 id,? 0.0 wa,? 0.0 hi,? 0.0 si,? 0.0 st
KiB Mem :? 1016884 total,??? 97184 free,??? 70848 used,?? 848852 buff/cache
KiB Swap:??????? 0 total,??????? 0 free,??????? 0 used.?? 782540 avail Mem

? PID USER????? PR? NI??? VIRT??? RES??? SHR S %CPU %MEM???? TIME+ COMMAND???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
root????? 20?? 0?? 29788?? 1256??? 988 S? 0.3? 0.1?? 0:01.50 elfin?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????


#3、
等待父進程正常結束后會調用wait/waitpid去回收僵尸進程
但如果父進程是一個死循環,永遠不會結束,那么該僵尸進程就會一直存在,僵尸進程過多,就是有害的
解決方法一:殺死父進程
解決方法二:對開啟的子進程應該記得使用join,join會回收僵尸進程
參考python2源碼注釋
class Process(object):
??? def join(self, timeout=None):
??????? '''
??????? Wait until child process terminates
??????? '''
??????? assert self._parent_pid == os.getpid(), 'can only join a child process'
??????? assert self._popen is not None, 'can only join a started process'
??????? res = self._popen.wait(timeout)
??????? if res is not None:
??????????? _current_process._children.discard(self)

join方法中調用了wait,告訴系統釋放僵尸進程。discard為從自己的children中剔除
解決方法三:http://blog.csdn.net/u010571844/article/details/50419798

四 守護進程

主進程創建守護進程

  其一:守護進程會在主進程代碼執行結束后就終止

  其二:守護進程內無法再開啟子進程,否則拋出異常:AssertionError: daemonic processes are not allowed to have children

注意:進程之間是互相獨立的,主進程代碼運行結束,守護進程隨即終止

from multiprocessing import Process
import time
import random

class Piao(Process):
??? def __init__(self,name):
??????? self.name=name
??????? super().__init__()
??? def run(self):
??????? print('%s is piaoing' %self.name)
??????? time.sleep(random.randrange(1,3))
??????? print('%s is piao end' %self.name)


p=Piao('egon')
p.daemon=True #一定要在p.start()前設置,設置p為守護進程,禁止p創建子進程,并且父進程代碼執行結束,p即終止運行
p.start()
print('主')
#主進程代碼運行完畢,守護進程就會結束
from multiprocessing import Process
from threading import Thread
import time
def foo():
??? print(123)
??? time.sleep(1)
??? print("end123")

def bar():
??? print(456)
??? time.sleep(3)
??? print("end456")


p1=Process(target=foo)
p2=Process(target=bar)

p1.daemon=True
p1.start()
p2.start()
print("main-------") #打印該行則主進程代碼結束,則守護進程p1應該被終止,可能會有p1任務執行的打印信息123,因為主進程打印main----時,p1也執行了,但是隨即被終止

?

轉載于:https://www.cnblogs.com/YZL2333/p/10445981.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/449809.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/449809.shtml
英文地址,請注明出處:http://en.pswp.cn/news/449809.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

LInux 下文件包的使用

1 .deb   http://wiki.ubuntu.org.cn/MySQL%E5%AE%89%E8%A3%85%E6%8C%87%E5%8D%97 2 .rpm

@RequiresPermissions 注解說明

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 RequiresAuthentication 驗證用戶是否登錄&#xff0c;等同于方法subject.isAuthenticated() 結果為true時。 RequiresUser 驗證用戶…

千位分隔符轉換為數字

最近下載了akshare里面的數據&#xff0c;然后發現有些數據格式為1,300這種格式&#xff0c;為str格式&#xff0c;但是又無法直接強制轉換之類方式&#xff0c;特地尋求答案&#xff0c;并做筆記&#xff0c;留待自己與后來者一起避坑。 from locale import * atof(123,456)…

一本通1629聰明的燕姿

1629&#xff1a;聰明的燕姿 時間限制: 1000 ms 內存限制: 524288 KB【題目描述】 城市中人們總是拿著號碼牌&#xff0c;不停尋找&#xff0c;不斷匹配&#xff0c;可是誰也不知道自己等的那個人是誰。 可是燕姿不一樣&#xff0c;燕姿知道自己等的人是誰&#xff0c;…

IT職場人生系列之二十四:程序員如何增加收入

這是IT職場人生系列的第二十四篇。&#xff08;序言&#xff0c;專欄目錄&#xff09; 程序員的收入是廣受關注的問題&#xff0c;很多人從業3&#xff5e;5年之后就會遇到這個收入瓶頸。盡管物價不斷上漲&#xff0c;程序員尤其是初、中級程序員的收入不升反降。即使上次在某…

ASP 代碼當前記錄集不支持更新問題的解決辦法。

錯誤類型&#xff1a;ADODB.Recordset (0x800A0CB3)當前記錄集不支持更新。這可能是提供程序的限制&#xff0c;也可能是選定鎖定類型的限制。 /Model/manage/Admin_Admin.asp, 第 35 行 找到放在數據庫文件的--- 右鍵--》屬性---》安全----》添加IIS來賓用戶---》權限為&#…

@PathVariable 注解 說明

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 PathVariable 映射 URL 綁定的占位符 帶占位符的 URL 是 Spring3.0 新增的功能&#xff0c;該功能在SpringMVC 向 REST 目標挺進發展過…

數據清洗,篩選

本人在私募&#xff0c;負責數據收集以及清洗&#xff0c;就是包括收集數據&#xff0c;按照領導要求&#xff0c;選出滿足條件的數據&#xff0c;用于校驗策略是否正確。 現在就在這進行代碼上傳&#xff0c;即用于自己總結整理&#xff0c;也用于供大家學習了解&#xff0c;實…

JS媒體查詢

樣式的改變使用C3的媒體查詢 行為和功能的改變使用JS的媒體查詢 matchMedia()方法參數可寫任何一個CSSmedia規則&#xff0c;返回的是新的MediaQueryList對象&#xff0c;該對象有兩個屬性 media&#xff1a;查詢語句的內容matches&#xff1a;檢查查詢結果&#xff0c;返回boo…

Ruby初步介紹

Ruby是腳本語言,與傳統的C, Java不同的是,它不需要經過編譯,而是直接可以被執行 Ubuntu下執行第一個ruby腳本 print("Hello David, This is your first Ruby script.\n") davidubuntu:~/RubyTrain/Basic$ ruby Hello.rb 運行結果: Hello David, This is your first R…

C/C++ main用法總結

今天看到一篇很好的文章&#xff0c;詳細的講解了C、C中的main函數&#xff0c;以及returne的用法。轉載過來大家一起分享下。轉自&#xff1a;http://www.cnblogs.com/ct6816678/archive/2012/10/26/2741824.htmlreturn是C預定義的語句&#xff0c;當return語句提供了一個值時…

如何將數據寫入excel中,而不覆蓋原有數據

之前直接用pandas庫&#xff0c;然后to_excel&#xff08;&#xff09;&#xff0c;結果直接將原始數據直接覆蓋&#xff0c;幸虧有備份。&#xff08;友善提醒&#xff0c;做數據處理之前&#xff0c;先將數據本地備份一份&#xff0c;確認完全沒有問題&#xff0c;然后還是備…

對List集合中的元素進行排序

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 ollections對List集合中的數據進行排序 有時候需要對集合中的元素按照一定的規則進行排序&#xff0c;這就需要用到 Java中提供的對集合…

Jmeter----5.1 設置中文

注意&#xff1a;JMeter5需要Java8 以上&#xff0c;本文環境是Win7 64位 設置永久默認漢化&#xff1a;在Jmeter的安裝目錄下的bin目錄中找到 jmeter.properties這個文件&#xff0c;用文本編輯器打開。在#languageen下面插入一行languagezh_CN 這樣&#xff0c;再次打開Jmete…

pandas計算移動平均值

本人今天遇到遇到一個任務&#xff0c;計算同月份合約當天各合約總持倉量的移動平均值。立刻寫下了這個函數&#xff1a; group df.groupby([合約系列,date]) f pd.DataFrame(group[持倉量].sum().rolling(20).mean()) 上交后&#xff0c;提出要求&#xff0c;不行&#xff…

一個優美的架構需要考慮的幾個問題

隨著公司的架構逐步發展&#xff0c;越來越多的問題被提出來&#xff0c;也發現一個良好的技術架構需要考慮的問題 1 架構的可擴展性 這里面又包括以下幾個方面 水平垂直可拆分服務無狀態數據可緩存可異步處理&#xff08;提高性能&#xff09;可復制&#xff08;提高效率&…

HSTS的來龍去脈

前言 安全經常說“云、管、端”&#xff0c;“管”指的是管道&#xff0c;傳輸過程中的安全。為了確保信息在網絡傳輸層的安全&#xff0c;現在很多網站都開啟了HTTPS&#xff0c;也就是HTTPTLS&#xff0c;在傳輸過程中對信息進行加密。HTTPS使用了對稱加密、非對稱加密、消息…

利用XShell上傳、下載文件(使用sz與rz命令) 超實用!

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 rz、sz 安裝方式&#xff1a;sz/rz命令安裝方式 借助XShell&#xff0c;使用linux命令sz可以很方便的將服務器上的文件下載到本地&#…

quantaxis使用docker安裝,解決了一個很奇特的問題

之前使用docker-compose pull 更新之后&#xff0c;使用docker-compose up進行安裝。出現 qaweb顯示address already in web,cmd中顯示Starting qa_web is wrong。之前一直覺得什么毛病啊&#xff0c;試了很多辦法。 比如關閉8010接口&#xff1a; netstat -ano|findstr “801…

基礎數學落后與高端人才流失

這個話題令人感到很痛苦&#xff0c;也很無奈。我本不該提起這個話題。但是&#xff0c;無窮小微積分專業網站不久即將開通&#xff0c;我不得不認真備課&#xff0c;仔細研讀 J.Keisler 的“初等微積分”電子版教材。在研究該教材內容的過程中&#xff0c;參照國內的《高等數學…