Latest web development tutorials

بيثون متعددة مؤشرات الترابط

مواضيع متعددة تنفيذها في وقت واحد مشابه لعدد من البرامج المختلفة، وتشغيل مؤشرات والمزايا التالية:

  • يمكن استخدام المواضيع تشغل برنامج طويل في مهمة في الخلفية للتعامل معها.
  • قد يكون واجهة المستخدم أكثر جاذبية، وذلك على سبيل المثال قيام المستخدم بالنقر فوق الزر لتحريك بعض معالجة الحدث، يمكنك البوب ​​شريط التقدم لإظهار التقدم في عملية
  • يمكن تشغيل سرعة تسريع
  • على أدركت بعض المهام، مثل انتظار إدخال المستخدم، وثيقة محو الأمية والشبكة لإرسال واستقبال البيانات، وموضوع هو أكثر فائدة. في هذه الحالة، يمكننا أن يحرر بعض الموارد القيمة، مثل استخدام الذاكرة وهلم جرا.

المواضيع في عملية التنفيذ وعملية مختلفة. كل لديه موضوع منفصل تشغيل الدخول والخروج تسلسل والإجراءات اللازمة لتنفيذ هذا الأمر. ولكن موضوع غير قادر على أداء بشكل مستقل، فإنه يجب أن يكون موجودا وفقا للتطبيق، وتوفير المواضيع تنفيذ عدة يسيطر عليها التطبيق.

كل موضوع له مجموعة بلده من سجلات وحدة المعالجة المركزية، ودعا سياق الموضوع، يعكس سياق موضوع في الماضي البعيد للدولة موضوع وحدة المعالجة المركزية السجل.

مؤشر التعليمة ومؤشر مكدس سجلات هما أهم سجلات سياق موضوع وموضوع دائما يحصل على تشغيل في سياق هذه العملية، يتم استخدام هذه العناوين للاحتفال العملية التي تمتلك موضوع مساحة عنوان الذاكرة.

  • الموضوع يمكن استبقت (توقف).
  • في تشغل المواضيع الأخرى، ويمكن عقد الخيط معلقا (المعروف أيضا باسم النوم) - وهذا هو موضوع من التنازلات.

البدء في تعلم المواضيع بيثون

المواضيع الثعبان تستخدم بطريقتين: مع وظيفة أو فئة التفاف الكائن الموضوع.

وظيفية: وظيفة الدعوة حدة موضوع start_new_thread () لإنشاء موضوع جديد. بناء الجملة كما يلي:

thread.start_new_thread ( function, args[, kwargs] )

المعلمة الوصف:

  • وظيفة - وظيفة موضوع.
  • وسائط - المعلمات موضوع تمريرها إلى وظيفة، لا بد له من أن يكون نوع الصفوف (tuple).
  • kwargs - اختياري.

على سبيل المثال:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import thread
import time

# 为线程定义一个函数
def print_time( threadName, delay):
   count = 0
   while count < 5:
      time.sleep(delay)
      count += 1
      print "%s: %s" % ( threadName, time.ctime(time.time()) )

# 创建两个线程
try:
   thread.start_new_thread( print_time, ("Thread-1", 2, ) )
   thread.start_new_thread( print_time, ("Thread-2", 4, ) )
except:
   print "Error: unable to start thread"

while 1:
   pass

نتائج الإخراج البرنامج المذكور أعلاه هي كما يلي:

Thread-1: Thu Jan 22 15:42:17 2009
Thread-1: Thu Jan 22 15:42:19 2009
Thread-2: Thu Jan 22 15:42:19 2009
Thread-1: Thu Jan 22 15:42:21 2009
Thread-2: Thu Jan 22 15:42:23 2009
Thread-1: Thu Jan 22 15:42:23 2009
Thread-1: Thu Jan 22 15:42:25 2009
Thread-2: Thu Jan 22 15:42:27 2009
Thread-2: Thu Jan 22 15:42:31 2009
Thread-2: Thu Jan 22 15:42:35 2009

نهاية موضوع بشكل عام تعتمد على النهاية الطبيعية وظيفة موضوع، ويمكن أيضا استدعاء وظيفة thread.exit موضوع ()، وقال انه يلقي استثناء SystemExit، تحقيق الغرض من الخروج الموضوع.


وحدة خيوط

يوفر بيثون دعم خيوط من خلال اثنين من المكتبات القياسية موضوع وخيوط. يوفر موضوع على مستوى منخفض، وموضوع الأصلي وقفل بسيط.

وتقدم أخرى وحدة موضوع وسائل:

  • threading.currentThread (): إرجاع متغير الترابط الحالي.
  • threading.enumerate (): إرجاع يحتوي على قائمة الموضوع قيد التشغيل. يشير تشغيل موضوع بدأ قبل النهاية، فإنه لا يشمل موضوع قبل البدء وبعد انتهاء.
  • threading.activeCount (): إرجاع عدد من المواضيع التي تعمل بنظام التشغيل، ولين (threading.enumerate ()) لديها نفس النتيجة.

بالإضافة إلى استخدام وسائل، ويوفر وحدة خيوط أيضا فئة الموضوع إلى معالجة موضوع، وتقدم الطبقة الموضوع الطرق التالية:

  • تشغيل (): للإشارة إلى طريقة المواضيع النشطة.
  • بدء (): بدء النشاط موضوع.

  • انضمام ([مرة]): انتظر حتى يتم إحباط الموضوع.هذا كتل يسمى موضوع الدعوة حتى طريقة لمؤشر الترابط انضمام () تعليق - خروج العادي أو رمي استثناء غير معالج - أو مهلة اختيارية يحدث.
  • isAlive (): إرجاع موضوع نشط.
  • getName (): إرجاع اسم الموضوع.
  • setName (): تعيين اسم الموضوع.

استخدام الخيوط وحدة لإنشاء المواضيع

استخدام وحدة خيوط لخلق موضوع، ورثت مباشرة من threading.Thread، ثم تجاوز __init__ أسلوب وطرق تشغيل:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import threading
import time

exitFlag = 0

class myThread (threading.Thread):   #继承父类threading.Thread
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
    def run(self):                   #把要执行的代码写到run函数里面 线程在创建后会直接运行run函数 
        print "Starting " + self.name
        print_time(self.name, self.counter, 5)
        print "Exiting " + self.name

def print_time(threadName, delay, counter):
    while counter:
        if exitFlag:
            thread.exit()
        time.sleep(delay)
        print "%s: %s" % (threadName, time.ctime(time.time()))
        counter -= 1

# 创建新线程
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)

# 开启线程
thread1.start()
thread2.start()

print "Exiting Main Thread"

نتائج تنفيذ البرنامج المذكور أعلاه هي على النحو التالي؛

Starting Thread-1
Starting Thread-2
Exiting Main Thread
Thread-1: Thu Mar 21 09:10:03 2013
Thread-1: Thu Mar 21 09:10:04 2013
Thread-2: Thu Mar 21 09:10:04 2013
Thread-1: Thu Mar 21 09:10:05 2013
Thread-1: Thu Mar 21 09:10:06 2013
Thread-2: Thu Mar 21 09:10:06 2013
Thread-1: Thu Mar 21 09:10:07 2013
Exiting Thread-1
Thread-2: Thu Mar 21 09:10:08 2013
Thread-2: Thu Mar 21 09:10:10 2013
Thread-2: Thu Mar 21 09:10:12 2013
Exiting Thread-2

تزامن الموضوع

إذا مواضيع متعددة من تعديل بيانات المشترك، قد تحدث نتائج غير متوقعة، وذلك لضمان دقة البيانات، ونحن بحاجة لمزامنة مواضيع متعددة.

كائن الموضوع باستخدام قفل وRlock يمكن تحقيق التزامن موضوع بسيط، الكائنين وطرق اكتساب وأساليب الإفراج، بالنسبة لأولئك الذين يحتاجون إلى السماح لكل بيانات التشغيل موضوع واحد فقط، ويمكن وضعها في اكتساب عملية والافراج عن أساليب غرفة. على النحو التالي:

خاصية تعدد ميزة هو أنه يمكن تشغيلها في وقت واحد مهام متعددة (على الأقل يشعر مثل هذا). ولكن عندما المواضيع تحتاج لتبادل البيانات، قد تكون هناك قضايا مزامنة البيانات.

النظر في القضية: قائمة بجميع العناصر هي صفر، وموضوع "مجموعة" من الخلف إلى الأمام على جميع العناصر في واحدة، وموضوع "طباعة" من الأمام إلى الخلف المسؤول من قراءة القائمة، والطباعة.

ثم، في موضوع قد يكون "مجموعة" بدأت تتغير عندما موضوع "طباعة" لطباعة قائمة، سيكون من نصف الناتج من نصف 0، والذي لم يتم مزامنة البيانات. لتجنب هذا الوضع، ونحن نقدم مفهوم القفل.

قفل ديه دولتين - مؤمن وغير مؤمن. كلما موضوع مثل "مجموعة" للوصول إلى البيانات المشتركة، يجب أولا الحصول على التأمين، وإذا كان لديك بالفعل موضوع آخر، مثل "طباعة" لنسجن، ثم ترك موضوع "تعيين" وقفة، وهو حجب متزامن؛ انتظر حتى موضوع " طباعة "اكتمال وصول، وبعد الافراج عن قفل، والسماح للموضوع" مجموعة "للمتابعة.

بعد هذه العملية، عندما قمت بطباعة قائمة من كافة الإخراج إما 0 أو 1 الانتاج الكامل، لم يعد يظهر نصف الإحراج 0 1 نصف.

على سبيل المثال:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import threading
import time

class myThread (threading.Thread):
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
    def run(self):
        print "Starting " + self.name
       # 获得锁,成功获得锁定后返回True
       # 可选的timeout参数不填时将一直阻塞直到获得锁定
       # 否则超时后将返回False
        threadLock.acquire()
        print_time(self.name, self.counter, 3)
        # 释放锁
        threadLock.release()

def print_time(threadName, delay, counter):
    while counter:
        time.sleep(delay)
        print "%s: %s" % (threadName, time.ctime(time.time()))
        counter -= 1

threadLock = threading.Lock()
threads = []

# 创建新线程
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)

# 开启新线程
thread1.start()
thread2.start()

# 添加线程到线程列表
threads.append(thread1)
threads.append(thread2)

# 等待所有线程完成
for t in threads:
    t.join()
print "Exiting Main Thread"

طابور الأولوية الموضوع (انتظار)

وتقدم وحدة الصف بايثون التزامن، والطبقات طابور موضوع آمنة، بما في ذلك FIFO (الأول في الأول من) قائمة انتظار طابور، إل آي إف (آخر في، أولا خارج) LifoQueue طابور، وPriorityQueue طابور الأولوية. ويتم تنفيذ هذه الطوابير قفل البدائيون يمكن استخدامها مباشرة في مواضيع متعددة. يمكنك استخدام قائمة انتظار لتحقيق التزامن بين المواضيع.

وحدة الصف الأساليب المستخدمة شيوعا:

  • Queue.qsize () إرجاع حجم قائمة الانتظار
  • Queue.empty () إذا قائمة الانتظار فارغة، بإرجاع True، الكاذبة والعكس بالعكس
  • Queue.full () إذا كانت قائمة الانتظار الكامل، والعودة صحيح، خطأ والعكس بالعكس
  • المقابلة لحجم وماكس سايز Queue.full
  • Queue.get ([كتلة [، مهلة]]) يحصل على قائمة الانتظار مهلة انتظار الوقت المناسب
  • Queue.get_nowait () بدلا Queue.get (خطأ)
  • Queue.put (البند) طابور الكتابة، مهلة انتظار الوقت المناسب
  • Queue.put_nowait (البند) تماما Queue.put (البند، خطأ)
  • Queue.task_done () بعد الانتهاء من العمل، Queue.task_done () يرسل إشارة وظيفة لهذه المهمة قد اكتملت طابور
  • Queue.join () يعني حقا حتى قائمة الانتظار فارغة، ثم إجراء عمليات أخرى

على سبيل المثال:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import Queue
import threading
import time

exitFlag = 0

class myThread (threading.Thread):
    def __init__(self, threadID, name, q):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.q = q
    def run(self):
        print "Starting " + self.name
        process_data(self.name, self.q)
        print "Exiting " + self.name

def process_data(threadName, q):
    while not exitFlag:
        queueLock.acquire()
        if not workQueue.empty():
            data = q.get()
            queueLock.release()
            print "%s processing %s" % (threadName, data)
        else:
            queueLock.release()
        time.sleep(1)

threadList = ["Thread-1", "Thread-2", "Thread-3"]
nameList = ["One", "Two", "Three", "Four", "Five"]
queueLock = threading.Lock()
workQueue = Queue.Queue(10)
threads = []
threadID = 1

# 创建新线程
for tName in threadList:
    thread = myThread(threadID, tName, workQueue)
    thread.start()
    threads.append(thread)
    threadID += 1

# 填充队列
queueLock.acquire()
for word in nameList:
    workQueue.put(word)
queueLock.release()

# 等待队列清空
while not workQueue.empty():
    pass

# 通知线程是时候退出
exitFlag = 1

# 等待所有线程完成
for t in threads:
    t.join()
print "Exiting Main Thread"

نتائج البرنامج أعلاه:

Starting Thread-1
Starting Thread-2
Starting Thread-3
Thread-1 processing One
Thread-2 processing Two
Thread-3 processing Three
Thread-1 processing Four
Thread-2 processing Five
Exiting Thread-3
Exiting Thread-1
Exiting Thread-2
Exiting Main Thread