Тот же самый программный вывод в модуле потоковой передачи

start.py приведен ниже.

import threading
class myThread(threading.Thread):
        def __init__(self, threadID, name):
                threading.Thread.__init__(self)
                self.threadID = threadID
                self.name = name

        def run(self):
                currentThreadname = threading.currentThread()
                print "running in ", currentThreadname

thread = myThread(1,"mythrd")
thread.start()

Запустите его с помощью python два раза.

python start.py
running in  <myThread(mythrd, started 140461133485824)>
python start.py
running in  <myThread(mythrd, started 140122860668672)>

run.py приведен ниже.

import threading
class myThread(threading.Thread):
        def __init__(self, threadID, name):
                threading.Thread.__init__(self)
                self.threadID = threadID
                self.name = name

        def run(self):
                currentThreadname = threading.currentThread()
                print "running in ", currentThreadname

thread = myThread(1,"mythrd")
thread.run()

run.py - только одна строка, отличная от start.py.
Теперь запустите run.py два раза.

python  run.py
running in  <_MainThread(MainThread, started 139854546364160)>
python  run.py
running in  <_MainThread(MainThread, started 139854546364160)>

Код startandrun.py выглядит следующим образом.

class myThread(threading.Thread):
    def __init__(self, threadID, name):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name

    def run(self):
        currentThreadname = threading.currentThread()
        print "running in ", currentThreadname

thread = myThread(1,"mythrd")
thread.start()
thread.run()

Теперь запустите startandrun.py еще два раза.

python  startandrun.py
running in  <myThread(mythrd, started 140317119899392)>
running in  <_MainThread(MainThread, started 140317144454912)>
python  startandrun.py
running in running in  <_MainThread(MainThread, started 139980210505472)>
 <myThread(mythrd, started 139980185949952)>

Как говорит JohanL:
При запуске двух отдельных потоков все ставки отключены относительно того, что будет выполняться в первую очередь.
Вы в основном оставляете планирование в операционной системе. При первом запуске startandrun.py, thread.start() выполнялся до thread.run(), он выводил результат:

running in  <myThread(mythrd, started 140317119899392)>
running in  <_MainThread(MainThread, started 140317144454912)>

Во второй раз для запуска startandrun.py, thread.start() был выполнен после thread.run(), почему бы не привести результат:

running in  <_MainThread(MainThread, started 140317144454912)>
running in  <myThread(mythrd, started 140317119899392)>

вместо

running in running in  <_MainThread(MainThread, started 139980210505472)>
 <myThread(mythrd, started 139980185949952)>

Ответ 1

Это происходит из-за того, как вы печатаете значения:

print "running in ", currentThreadname

Добавление запятой аналогично:

print 'running in ' # without new line at the end
print currentThreadname

И поскольку две функции работают одновременно, вот как выполняется порядок:

print 'running in ' # without new line FUNCTION #1
print 'running in ' # without new line FUNCTION #2
print currentThreadName # with new line at the end FUNCTION #1
print currentThreadName # with new line at the end FUNCTION #2

Попробуйте использовать один оператор печати без запятых, чтобы понять, как это должно быть:

def run(self):
    currentThreadname = threading.currentThread()
    print "running in {}".format(currentThreadname)

Это будет вести себя нормально, но поскольку две функции печатаются одновременно, вы можете получить следующий вывод:

running in <myThread(mythrd, started 10716)>running in <_MainThread(MainThread, started 12132)>

Итак, чтобы доказать, что это будет работать, вы можете использовать задержку между двумя вызовами с помощью time.sleep():

import threading
import time

class myThread(threading.Thread):
    def __init__(self, threadID, name):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name

    def run(self):
        currentThreadname = threading.currentThread()
        print "running in {}".format(currentThreadname)

thread = myThread(1,"mythrd")
thread.start()
time.sleep(0.1)
thread.run()

Теперь вы можете видеть, что вы получаете желаемый результат, потому что каждая функция печатает один раз с задержкой 0,1 с между вызовами:

running in <myThread(mythrd, started 5600)>
running in <_MainThread(MainThread, started 7716)>

EDIT:

Ваша проблема именно в том, почему вы должны использовать многопоточность вместо того, чтобы дважды запускать тот же поток. Когда вы используете многопоточность, вы можете использовать thread.join(), который будет ждать завершения потока, а затем продолжить код, или вы можете использовать threading.lock(), чтобы вы могли продолжить свой код, но заблокировать функцию использовать один поток за раз. Вот несколько примеров:

Thread.join():

thread = myThread(1, "mythrd")
thread2 = myThread(2, "thrd2")
thread.start()
thread.join() # code will stop here and wait for thread to finish then continue
thread2.run()

threading.lock():

....
    def run(self):
        with lock: # if one thread uses this lock the other threads have to wait
            currentThreadname = threading.currentThread()
            print "running in ", currentThreadname

thread = myThread(1, "mythrd")
thread2 = myThread(2, "thrd2")
lock = threading.Lock()
thread.start() 
thread2.run()
# code keeps running even if there are threads waiting for the lock

Ответ 2

Итак, все, что вам нужно, это синхронизация ваших потоков. Это можно сделать легко, используя функцию join() в библиотеке потоков.

Вы можете сделать что-то вроде этого

class myThread(threading.Thread):
    def __init__(self, threadID, name):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name

    def run(self):
        currentThreadname = threading.currentThread()
        print "running in ", currentThreadname

thread = myThread(1,"mythrd")
t1 =  thread.start()
t1.join()
t2 =  thread.run()
t2.join()

Вы также можете использовать семафор и блокировку по лучшим причинам. Подробнее см. В документах.

Ответ 3

Возможно, вы не понимаете, как работают потоки. Внимательно прочитайте .

Я настоятельно рекомендую вам использовать ThreadPoolExecutor в библиотеке futures.

Ответ 4

Какую версию python вы использовали? В python 2 "print" не является потокобезопасным. См. http://tech.queryhome.com/54593/is-print-thread-safe-in-python-2-6-2-7.

Если потоки переключаются во время "печати", выходы смешиваются, как то, что вы видели.