Ufder
Ufder

Reputation: 537

Global method with local variables thread safety

I have a python project where I am adding a new file utils.py with the below content. It is going to be accessed by different threads.

def get_return_string(input_string, input_dict):
    ret_str = 'some default value'
    if 'apple' in input_string:
        ret_str = input_dict['apple']
    elif 'banana' in input_string:
        ret_str = input_dict['banana']
    elif 'grapes' in input_string:
        ret_str = input_dict['grapes']
    elif 'spinach' in input_string:
        ret_str = input_dict['spinach']
    elif 'orange' in input_string:
        ret_str = input_dict['orange']
    elif 'berry' in input_string:
        ret_str = input_dict['berry']
    return ret_str

There are only local variables and they are called from inside instances of another class(es). Is this method thread safe?

I read here that:

Local variables are certainly "thread-exclusive." No other thread can access them directly, and this is helpful but not sufficient to guarantee semantic thread safety. A local variable in one thread does not store its value in the same location as the same-named local variable in another thread

and

However, guaranteeing that two threads have separate storage for local variables is not enough to ensure thread-safety, because those local variables can refer to globally shared data in a thread-unsafe way.

Also will this method behave any differently if it is a class method instead of a global method:

class Utils():

    @classmethod
    def get_return_string(cls, input_string, input_dict):
        #...same as above...

Upvotes: 2

Views: 838

Answers (1)

Devesh Kumar Singh
Devesh Kumar Singh

Reputation: 20490

Yes, the function is thread safe since the local variables are actually not accessing any global variables, and you can check by printing the value of ret_str in the method

def get_return_string(input_string, input_dict):
    ret_str = 'some default value'
    if 'apple' in input_string:
        ret_str = input_dict['apple']
    elif 'banana' in input_string:
        ret_str = input_dict['banana']
    elif 'grapes' in input_string:
        ret_str = input_dict['grapes']
    elif 'spinach' in input_string:
        ret_str = input_dict['spinach']
    elif 'orange' in input_string:
        ret_str = input_dict['orange']
    elif 'berry' in input_string:
        ret_str = input_dict['berry']
    print(ret_str)
    return ret_str

from threading import Thread

dct = {'apple':1,'banana':2}
t1 = Thread(target=get_return_string, args=('apple',dct))
t2 = Thread(target=get_return_string, args=('fruit',dct))
t3 = Thread(target=get_return_string, args=('banana',dct))
t1.start()
t2.start()
t3.start()
t1.join()
t2.join()
t3.join()
#1
#some default value
#2

Upvotes: 2

Related Questions