CX_ORACLE ، المولدات ، والمواضيع في بيثون
-
22-09-2019 - |
سؤال
ما هو سلوك مؤشرات CX_ORACLE عند استخدام كائن الاتصال بواسطة مؤشرات ترابط مختلفة؟ كيف ستؤثر المولدات على هذا السلوك؟ على وجه التحديد...
تعديل: كانت وظيفة المثال الأصلي غير صحيحة ؛ تم إرجاع مولد من خلال وظيفة فرعية ، yield
لم يتم استخدامه مباشرة في الحلقة. هذا يوضح متى finally
يتم تنفيذها (بعد return
هل) ، ولكن لا يزال لا يجيب على ما إذا كان يمكن استخدام المؤشر إذا بدأ مؤشر ترابط آخر في استخدام كائن الاتصال الذي تم إنشاء المؤشر منه. يبدو في الواقع (في بيثون 2.4 ، على الأقل) ، try...finally
مع yield
يسبب خطأ بناء الجملة.
def Get()
conn = pool.get()
try:
cursor = conn.cursor()
cursor.execute("select * from table ...")
return IterRows(cursor)
finally:
pool.put(conn)
def IterRows(cursor):
for r in cursor:
yield r
Get()
هي وظيفة تسمى مؤشرات ترابط متعددة. يتم إنشاء الاتصالات مع threaded=False
جدال.
انا اتسائل...
- هو الموضوع 1
cursor
الكائن لا يزال قابلاً للاستخدام إذا جاء الموضوع 2 ويستخدم نفس كائن الاتصال؟ إذا لم يكن كذلك ، ماذا قد يحدث؟
السلوك الذي أراه هو استثناء في CX_ORACLE يتحدث عن خطأ بروتوكول ، ثم يتبع segfault.
المحلول
يرى المستندات: threadsafety
هو ، وأنا أقتبس ،
حاليا 2 ، مما يعني أن المواضيع قد تشارك الوحدة والاتصالات ، ولكن ليس المؤشرات.
لذا ، يبدو أن بنية "مجموعة المؤشرات" الخاصة بك (حيث يمكن استخدام مؤشر واحد من قبل مؤشرات ترابط مختلفة) خارج threadsafety
مستوى. إنها ليست مشكلة في مشاركة الاتصالات (هذا جيد منذ مرورك threaded
بشكل صحيح في مُنشئ الاتصال) ولكن المؤشرات. قد ترغب في تخزين كل مؤشر threading.local
بعد المرة الأولى التي يستخدمها مؤشر ترابط ، بحيث يمكن أن يكون لكل مؤشر ترابط "تجمع" واحد (ليس تحسينًا رئيسيًا ، على الرغم من: صنع المؤشر الجديد ليس عملية شاقة).
wrt سؤالك 2 ، finally
يتم تنفيذ البند عندما يكون كائن المولد (تم تصميمه بواسطة مكالمة إلى وظيفة المولد الخاصة بك Get
) يتم كل ذلك - إما لأنه يرفع StopIteration
, ، أو لأنه يجري جمع القمامة (عادةً لأن الإشارة الأخيرة إليها قد اختفت للتو). على سبيل المثال ، إذا كان المتصل هو:
def imthecaller():
for i, row in enumerate(Get()):
print i, row
if i > 1: break
# this is the moment the generators' finally-clause runs
print 'bye'
ال finally
ينفذ بعد (على الأكثر) 3 صفوف yield
إد.