פורסם: 19/02/2021 - 11:49
נושא ההודעה: ריצה מקבילית בפייתון: threading או multiprocessing
|
אני כותב קוד שבצע מספר רב של פעולות שמבחינת משאבי מיחשוב דורשות מעט מאד אך זמן הביצוע של כל אחת מגיע לעשרות שניות. אין קשר או תלות בין הפעולות.
אני רוצה להריץ את כולן במקביל, מה ההבדלים בין threading ל-multiprocessing? האם יש עדיפות לאחת מהן כשמה שנדרש לביצוע הוא חיבור לציוד רשת מרוחק, הרצת מספר פקודות על הציוד ואיסוף של המידע שהתקבל לתוך רשימה או קובץ json?
תודה !
_________________ איזי גולדנברג
|
|
חזרה לתוכן הדיון |
פורסם: 19/02/2021 - 15:36
נושא ההודעה:
|
מוסיף לשאלה מעל, אני מנסה כרגע לעבוד עם multiprocessing ומתקשה להבין איך אני מחזיר ערך לפונקציה שהריצה את ה-process?
לדוגמה:
[code]
def return_multi(some_value):
return some_value*2
jobs = []
for i in range(5):
p = multiprocessing.Process(target=return_multi, args=(i,))
jobs.append(p)
p.start()
[code][/code]
קראתי קצת על shared memory ו-server process אבל אני שואל את עצמי (ואת חברי הפורום) האם ישנה דרך "רגילה" לקרא את הערך שמוחזר מכל instance שרץ?
האם בשימוש ב-threading ישנה אפשרות כזו?
או שאופן העבודה במקביל לא מאפשר את זה.
_________________ איזי גולדנברג
|
|
חזרה לתוכן הדיון |
פורסם: 19/02/2021 - 23:03
נושא ההודעה:
|
תתחיל מ-threading זה הפתרון שיש לו פחות overhead ויותר מתאים למה שאתה מתאר. אם המהירות מוגבלת בעיקר בגלל תקשורת שמחכה לצד השני להגיב אז יש עוד פתרון והוא event driven או מה שנקרא reactive שמאפשר לעשות את הפעולות במקביל בלי שנדרש thread נפרד לכל פעולה.
|
|
חזרה לתוכן הדיון |
פורסם: 20/02/2021 - 02:01
נושא ההודעה: Re: ריצה מקבילית בפייתון: threading או multiprocessing
|
COM64 : | אני כותב קוד שבצע מספר רב של פעולות שמבחינת משאבי מיחשוב דורשות מעט מאד אך זמן הביצוע של כל אחת מגיע לעשרות שניות. אין קשר או תלות בין הפעולות.
אני רוצה להריץ את כולן במקביל, מה ההבדלים בין threading ל-multiprocessing? האם יש עדיפות לאחת מהן כשמה שנדרש לביצוע הוא חיבור לציוד רשת מרוחק, הרצת מספר פקודות על הציוד ואיסוף של המידע שהתקבל לתוך רשימה או קובץ json?
תודה ! |
כלל אצבע - תקודד עם threads (שרצים על אותו מעבד כמו האבא שהריץ אותם), תסתכל ב top - אם ניצול מעבד נשאר על 100% לאורך זמן, אולי כדאי לשקול שימוש במעבדים האחרים, ז"א multi-processing.
|
|
חזרה לתוכן הדיון |
פורסם: 20/02/2021 - 08:58
נושא ההודעה:
|
תודה על שתי התגובות.
אז חזרתי ל-threads והתחלתי ללמוד את נושא ה-event driven.
המעבד ירוץ בעומס נמוך לפחות בתחילת הדרך, רוב הזמן הוא פשוט ממתין לציוד שיחזיר תשובה.
_________________ איזי גולדנברג
|
|
חזרה לתוכן הדיון |
פורסם: 21/02/2021 - 15:49
נושא ההודעה: שאלה של מי שלא נגע בפיתון בעשר שנים אחרונות
|
האם יש עדיין הגיון להשתמש בprocesses כמו פעם ותורים או פשוט לכתוב א-סינכרוני?
קוד: |
import asyncio
async def myfunc():
return 42
|
כלומר 1ץ האם לא ניתן להניח שא-סינכרוני בפיתון הוא לא כמו javascript והוא רץ ב theread נפרד?
2. כמו ב c++ הוא יודיע אוטומטית כמה מעבדים על המכונה ויודיע לפתוח בו זמנית את הכמות הנידרשת?
- אני באמת לא יודיע python ולא נגעתי בשפה ב 10 שנים אחרונות....
|
|
חזרה לתוכן הדיון |
פורסם: 21/02/2021 - 15:58
נושא ההודעה:
|
בהמשך ל 1 ו- 2 ממיקודם..
3. גם תכנות א-סינכרוני יפתור בעיות של shared memory מה שב c#/c++ דורש mux וכאלה..?
|
|
חזרה לתוכן הדיון |
פורסם: 21/02/2021 - 18:25
נושא ההודעה:
|
python פשוט לא תומכת ב multi-threadings שמשתמש ב multi-core. כשאתה יוצר thread בפייתון, הוא תמיד רץ על אותו מעבד כמו האבא. זה מה יש.
מזכיר לי שורת הערה שראיתי בקוד רלוונטי, שבו כתוב (תרגום עקום): "אני מפחד לחפש בגוגל איך לפתור את הבעיה - כיצד הורה יכול להרוג את הילד..." חוש הומור של מפתחים
|
|
חזרה לתוכן הדיון |
פורסם: 24/02/2021 - 23:42
נושא ההודעה:
|
Anonymous : | python פשוט לא תומכת ב multi-threadings שמשתמש ב multi-core. כשאתה יוצר thread בפייתון, הוא תמיד רץ על אותו מעבד כמו האבא. זה מה יש.
מזכיר לי שורת הערה שראיתי בקוד רלוונטי, שבו כתוב (תרגום עקום): "אני מפחד לחפש בגוגל איך לפתור את הבעיה - כיצד הורה יכול להרוג את הילד..." חוש הומור של מפתחים |
הערה מצחיקה.
אבל החלק הראשון לא ממש מדויק. יש אפשרות להריץ קוד על הרבה ליבות, אבל זה לא חלק מהספריות הסטנדרטיות.
השאלה המקורית אומרת שהקוד מחכה לתשובה, במקרים כאלו - Thread שתופס ליבה של המעבד כמו בג'אווה זה פשוט בזבוז. Python Threads מספיקים בהחלט רב.
בהפשטה רבה מאוד - Thread בשפות תכנות אחרות נקרא Process בפייתון.
אבל כמו שאמרתי לא צריך את זה ב-99% כשלא מדובר בפעולות חשוב אינטנסיביות.
במקרה המדובר אפשר גם להשתמש ב-Async.
|
|
חזרה לתוכן הדיון |
פורסם: 25/02/2021 - 20:50
נושא ההודעה:
|
אם אתה שואל אותי THREAD זה תכנות לקוי.
אני בכלל לא מדבר על הDEBUG שיהיה סיוט.
ובכל מקרה אולי עדיף להשתמש בזה בצורה חיצונית
עם ספרייה חיצונית.
תכנות בריא זה קוד פשוט שרץ על PROCESS פשוט
וניתן להפעיל אותו את מספר הפעמים שאתה צריך.
כל הPROCESS ירוצו על המעבד שהמערכת תקצה לו
MULTI CORE או CORE אחד שקוף ופשוט.
עדיף לבנות רכיב חיצוני שעושה POOL ומשתמש אולי ב QUEUE
או שמייצר INDEX לכל תהליך שפונה אליו .
אם תהיה יותר פרטני יביאו לך רעיונות לפתרון שאולי בכלל לא חשבת
עליהם ומפשטים את הקוד.
_________________ מערכת: GNU/Linux debian
|
|
חזרה לתוכן הדיון |
פורסם: 26/02/2021 - 08:37
נושא ההודעה:
|
queency : | אם תהיה יותר פרטני יביאו לך רעיונות לפתרון שאולי בכלל לא חשבת
עליהם ומפשטים את הקוד. |
ניקח דוגמה פשוטה, אני כותב קוד שמבצע SSH לסוויץ, מריץ עליו פקודה ואת הפלט אני מכניס ל-Dictionary.
החיבור ב-SSH לוקח כמה שניות כשכל השאר מסתיים בהרבה פחות משניה. אני צריך להריץ את הפקודה על אלפי סוויצים ולכן חייב להריץ במקביל.
לצורך התרגול, נניח שלא ניתן להשתמש בפתרון חיבור אחר וחובה להשתמש ב-SSH.
השאלה שלי היא איך כל פרוסס מחזיר לי את הפלט ואותו אני אכניס לרשימה או מילון יחיד.
כבר חשבתי להשתמש בבסיס נתונים כלשהו, להכניס את הפלט ל-json ולשמור בבסיס הנתונים. כך אין לי התעסקות עם החזרה של הפלט לפרוסס האבא שקרא לכל הפרוססים במקביל.
_________________ איזי גולדנברג
|
|
חזרה לתוכן הדיון |
פורסם: 26/02/2021 - 08:56
נושא ההודעה:
|
מה לגבי שימוש במשהו קיים במקום להמציא את הגלגל
https://parallel-ssh.readthedocs.io
|
|
חזרה לתוכן הדיון |
פורסם: 26/02/2021 - 14:05
נושא ההודעה:
|
אם יש צורך בניהול מקביל של פעולות שונות ולא רק ssh אז - שרת ג׳ובים
https://edgeguides.rubyonrails.org/active_job_basics.html
או משהוא דומה שיש ב python
כי אחרת יש עוד דברים שלא חשבתה עליהם (מה אם הפרוסס מת באופן לא צפוי ועוד...)
|
|
חזרה לתוכן הדיון |
פורסם: 26/02/2021 - 18:00
נושא ההודעה:
|
נראה שזה לא עובד עם פייתון 3.7 כשיש צורך לבצע לוגין ב-SSH עם שם משתמש וסיסמה. יש באג על זה מ-2018 והגירסה העדכנית ביותר גם מ-2018. במקרה שלי לא קיימת אפשרות להשתמש במפתחות.
ממשיך לבדוק אם יש לזה פתרון כלשהו היות שזה נראה לפחות לשלב בו אני נמצא פתרון מספק.
_________________ איזי גולדנברג
|
|
חזרה לתוכן הדיון |
פורסם: 26/02/2021 - 18:02
נושא ההודעה:
|
בשלב הנוכחי אני רוצה רק לבדוק היתכנות ולכן חיפשתי משהו שיהיה פשוט ליישום. צודק לגבי נושאים רבים שעדיין אני לא חושב עליהם וידרשו יותר מחיבור והמתנה למענה.
_________________ איזי גולדנברג
|
|
חזרה לתוכן הדיון |
פורסם: 26/02/2021 - 21:41
נושא ההודעה:
|
ציטוט: | נראה שזה לא עובד עם פייתון 3.7 כשיש צורך לבצע לוגין ב-SSH עם שם משתמש וסיסמה. יש באג על זה מ-2018 והגירסה העדכנית ביותר גם מ-2018. במקרה שלי לא קיימת אפשרות להשתמש במפתחות |
אפשר לשאול איפה אתה רואה את זה?
אני רואה גרסאות מ-2021 והקוד ב-github מתוחזק עם תיקונים ושינויים שוטפים.
|
|
חזרה לתוכן הדיון |
פורסם: 27/02/2021 - 10:31
נושא ההודעה:
|
Anonymous : | ציטוט: | נראה שזה לא עובד עם פייתון 3.7 כשיש צורך לבצע לוגין ב-SSH עם שם משתמש וסיסמה. יש באג על זה מ-2018 והגירסה העדכנית ביותר גם מ-2018. במקרה שלי לא קיימת אפשרות להשתמש במפתחות |
אפשר לשאול איפה אתה רואה את זה?
אני רואה גרסאות מ-2021 והקוד ב-github מתוחזק עם תיקונים ושינויים שוטפים. |
צודק, טעיתי אחרי שראיתי את גרסה 1.6.0 באתר הזה https://parallel-ssh.org/. בפועל אני רואה שמותקנת אצלי גירסה 2.3.1
דוגמה לקוד שאני מנסה להריץ:
קוד: | from pssh.clients import ParallelSSHClient
hosts = [‘10.0.0.204’, ‘10.0.0.205’]
client = ParallelSSHClient(hosts, user = ‘admin’, password = ‘123456’)
client.run_command(‘show run’) |
והודעת השגיאה:
קוד: | Traceback (most recent call last):
File “/usr/local/lib/python3.7/dist-packages/pssh/clients/base/single.py”, line 208, in _auth_retry
self.auth()
File “/usr/local/lib/python3.7/dist-packages/pssh/clients/base/single.py”, line 355, in auth
self._password_auth()
File “/usr/local/lib/python3.7/dist-packages/pssh/clients/native/single.py”, line 229, in _password_auth
self.session.userauth_password(self.user, self.password)
File “ssh2/session.pyx”, line 321, in ssh2.session.Session.userauth_password
File “ssh2/utils.pyx”, line 166, in ssh2.utils.handle_error_codes
ssh2.exceptions.AuthenticationError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File “/usr/local/lib/python3.7/dist-packages/pssh/clients/base/single.py”, line 208, in _auth_retry
self.auth()
File “/usr/local/lib/python3.7/dist-packages/pssh/clients/base/single.py”, line 355, in auth
self._password_auth()
File “/usr/local/lib/python3.7/dist-packages/pssh/clients/native/single.py”, line 229, in _password_auth
self.session.userauth_password(self.user, self.password)
File “ssh2/session.pyx”, line 321, in ssh2.session.Session.userauth_password
File “ssh2/utils.pyx”, line 166, in ssh2.utils.handle_error_codes
ssh2.exceptions.AuthenticationError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File “/usr/local/lib/python3.7/dist-packages/pssh/clients/base/single.py”, line 208, in _auth_retry
self.auth()
File “/usr/local/lib/python3.7/dist-packages/pssh/clients/base/single.py”, line 355, in auth
self._password_auth()
File “/usr/local/lib/python3.7/dist-packages/pssh/clients/native/single.py”, line 229, in _password_auth
self.session.userauth_password(self.user, self.password)
File “ssh2/session.pyx”, line 321, in ssh2.session.Session.userauth_password
File “ssh2/utils.pyx”, line 166, in ssh2.utils.handle_error_codes
ssh2.exceptions.AuthenticationError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File “”, line 1, in
File “/usr/local/lib/python3.7/dist-packages/pssh/clients/native/parallel.py”, line 217, in run_command
return_list=return_list, read_timeout=read_timeout if read_timeout else timeout,
File “/usr/local/lib/python3.7/dist-packages/pssh/clients/base/parallel.py”, line 198, in run_command
return_list=return_list)
File “/usr/local/lib/python3.7/dist-packages/pssh/clients/base/parallel.py”, line 204, in _get_output_from_cmds
finished = joinall(_cmds, raise_error=True)
File “src/gevent/greenlet.py”, line 849, in gevent._greenlet.joinall
File “src/gevent/greenlet.py”, line 865, in gevent._greenlet.joinall
File “src/gevent/greenlet.py”, line 312, in gevent._greenlet.Greenlet._raise_exception
File “/usr/lib/python3/dist-packages/gevent/_compat.py”, line 47, in reraise
raise value.with_traceback(tb)
File “src/gevent/greenlet.py”, line 716, in gevent._greenlet.Greenlet.run
File “/usr/local/lib/python3.7/dist-packages/pssh/clients/base/parallel.py”, line 216, in _get_output_from_greenlet
raise ex
File “/usr/local/lib/python3.7/dist-packages/pssh/clients/base/parallel.py”, line 209, in _get_output_from_greenlet
host_out = cmd.get()
File “src/gevent/greenlet.py”, line 633, in gevent._greenlet.Greenlet.get
File “src/gevent/greenlet.py”, line 312, in gevent._greenlet.Greenlet._raise_exception
File “/usr/lib/python3/dist-packages/gevent/_compat.py”, line 47, in reraise
raise value.with_traceback(tb)
File “src/gevent/greenlet.py”, line 716, in gevent._greenlet.Greenlet.run
File “/usr/local/lib/python3.7/dist-packages/pssh/clients/base/parallel.py”, line 285, in _run_command
raise ex
File “/usr/local/lib/python3.7/dist-packages/pssh/clients/base/parallel.py”, line 277, in _run_command
_client = self._make_ssh_client(host_i, host)
File “/usr/local/lib/python3.7/dist-packages/pssh/clients/native/parallel.py”, line 252, in _make_ssh_client
identity_auth=self.identity_auth,
File “/usr/local/lib/python3.7/dist-packages/pssh/clients/native/single.py”, line 129, in init
identity_auth=identity_auth)
File “/usr/local/lib/python3.7/dist-packages/pssh/clients/base/single.py”, line 195, in init
self._init()
File “/usr/local/lib/python3.7/dist-packages/pssh/clients/base/single.py”, line 200, in _init
self._auth_retry()
File “/usr/local/lib/python3.7/dist-packages/pssh/clients/base/single.py”, line 212, in _auth_retry
return self._auth_retry(retries=retries+1)
File “/usr/local/lib/python3.7/dist-packages/pssh/clients/base/single.py”, line 212, in _auth_retry
return self._auth_retry(retries=retries+1)
File “/usr/local/lib/python3.7/dist-packages/pssh/clients/base/single.py”, line 214, in _auth_retry
raise AuthenticationError(msg, self.host, self.port, ex)
pssh.exceptions.AuthenticationError: (‘Authentication error while connecting to %s:%s - %s’, ‘10.0.0.204’, 22, AuthenticationError()) |
|
|
חזרה לתוכן הדיון |
פורסם: 27/02/2021 - 11:51
נושא ההודעה:
|
OK נראה שהבעיה ב"צד השני". כל הניסיונות שלי היו מול סוויצים וירטואלים של אריסטה בגירסה vEOS 4.25.1F
לעומת זאת, מול דביאן וסוויץ של סיסקו זה עובד.
מוריד גירסה אחרונה של אריסטה וסיסקו ואעדכן.
_________________ איזי גולדנברג
|
|
חזרה לתוכן הדיון |
פורסם: 28/02/2021 - 10:24
נושא ההודעה:
|
אם העבודה היא חיבורי ssh מרובים, ואין לך בעיה לעבוד async הייתי ממליץ לך על AsyncSSH.
|
|
חזרה לתוכן הדיון |
|