Что такое “локальная память потока” в Python, и почему мне нужен он?

Я нашел отзыв о подсказке полезным, чтобы устранить эту проблему в Tomcat -

, обязательно загрузите драйвер, сначала выполнив Class.forName («org.postgresql.Driver»); в вашем коде.

Это из сообщения - https://www.postgresql.org/message-id/e13c14ec050510103846db6b0e@mail.gmail.com

Код jdbc работал нормально как автономная программа, но в TOMCAT он дал ошибку «Не найден подходящий драйвер»

90
задан Shog9 11 September 2009 в 01:14
поделиться

4 ответа

В Python все совместно используется, за исключением функциональных локальных переменных (потому что каждый вызов функции получает свою собственную группу местных жителей, и потоки всегда являются вызовами отдельной функции.) И даже тогда, только сами переменные (имена, которые относятся к объектам) локальны для функции; сами объекты всегда глобальны, и что-либо может относиться к ним. Эти Thread объект для конкретного потока не является специальным объектом в этом отношении. Если Вы храните эти Thread объект где-нибудь, все потоки могут получить доступ (как глобальная переменная) тогда, все потоки могут получить доступ к тот одному Thread объект. Если Вы хотите атомарно изменить что-нибудь , что Вы только создали в этом очень тот же поток и не сохранили нигде другой поток, может достигнуть его, необходимо защитить его блокировкой. И все потоки должны, конечно, совместно использовать это очень та же блокировка, или это не было бы очень эффективно.

, Если Вы хотите фактическую локальную память потока, это - то, где threading.local входит. Атрибуты threading.local не совместно используются потоками; каждый поток видит только атрибуты, которые он сам поместил туда. Если Вам любопытно на предмет его реализации, источник находится в _threading_local.py в стандартной библиотеке.

77
ответ дан Pramod 24 November 2019 в 07:04
поделиться

Можно создать локальную память потока с помощью threading.local().

>>> tls = threading.local()
>>> tls.x = 4 
>>> tls.x
4

Данные, хранившие к tls, будут уникальны для каждого потока, который поможет гарантировать, что неумышленное совместное использование не происходит.

17
ответ дан Shog9 24 November 2019 в 07:04
поделиться

Точно так же, как на любом языке, каждый поток в Python имеет доступ к тем же переменным. Нет никакого различия между 'основным потоком' и дочерними потоками.

Одно различие с Python - то, что Глобальная Блокировка Интерпретатора означает, что только один поток может выполнять код Python за один раз. Это не много справки когда дело доходит до синхронизирующегося доступа, однако, поскольку все обычные проблемы вытеснения все еще применяются, и необходимо использовать примитивы поточной обработки точно так же, как на других языках. Это действительно означает, что необходимо пересмотреть при использовании потоков для производительности, как бы то ни было.

2
ответ дан Nick Johnson 24 November 2019 в 07:04
поделиться

Рассмотрим следующий код:

#/usr/bin/env python

from time import sleep
from random import random
from threading import Thread, local

data = local()

def bar():
    print("I'm called from", data.v)

def foo():
    bar()

class T(Thread):
    def run(self):
        sleep(random())
        data.v = self.getName()   # Thread-1 and Thread-2 accordingly
        sleep(1)
        foo()
 >> T().start(); T().start()
I'm called from Thread-2
I'm called from Thread-1 

Здесь threading.local () используется как быстрый и грязный способ передать некоторые данные из run () в bar () без изменения интерфейса foo ().

Обратите внимание, что использование глобальных переменных не поможет:

#/usr/bin/env python

from time import sleep
from random import random
from threading import Thread

def bar():
    global v
    print("I'm called from", v)

def foo():
    bar()

class T(Thread):
    def run(self):
        global v
        sleep(random())
        v = self.getName()   # Thread-1 and Thread-2 accordingly
        sleep(1)
        foo()
 >> T().start(); T().start()
I'm called from Thread-2
I'm called from Thread-2 

Между тем, если бы вы могли позволить себе передавать эти данные в качестве аргумента функции foo () - это был бы более элегантный и хорошо продуманный способ:

from threading import Thread

def bar(v):
    print("I'm called from", v)

def foo(v):
    bar(v)

class T(Thread):
    def run(self):
        foo(self.getName())

Но это не всегда возможно при использовании стороннего или плохо разработанного кода.

68
ответ дан 24 November 2019 в 07:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: