python thread base

A basic concept

1 Parallel and concurrent

1 parallel

Do something at the same time, you can do something at the same time without interrupting each other
For example, a lane on a highway can have multiple non-intrusive vehicles running at the same time
It is a concept that at the same time a vehicle may be running on each lane.

2 Concurrent, concurrency

It's also about doing something at the same time, but it emphasizes doing several things at the same time.
Parallelism solves concurrency problems.

2 Concurrent resolution

1 Queue, Buffer

Queue: Queue is the queue, FIFO solves the problem of resource use.
Buffer: A queue that is scheduled is actually a buffer, a buffer
Priority Queue: Handle more important things in a timely manner, here is the priority queue

2 Competition

Open only one window, there may be no order, that is, whoever squeezes in will cook for whoever
People crowded into the window occupy the window until they have reached the meal and left. Others continue to compete. One person will occupy the window, which can be regarded as locking the window. The window can no longer provide services to others. This is a locking mechanism. When resources are seized, the lock is locked, exclusive lock is locked, others can only wait.

Competition is also a high concurrency solution, but it's not good because someone may not be able to do it for a long time.

3 Preprocessing

A way of thinking to load data that users need in advance, such as preheating, preloading, etc., commonly used in caching
The idea of caching is to take the data directly and process it.

4 Parallel

Concurrency problems can be solved by purchasing more servers or multithreading for parallel processing, which are horizontal extensions.

5 Speed Up

Increase single CPU performance, or install more CPUs on a single server, but this is more costly than multiple servers

6 Message Middleware

Using intermediate buffers to solve concurrency problems, such as rabbitmq, activemq,rocketmq, kafka, etc., CDN is also a kind of

3 Process and Thread Concepts

1 Process and Threads

In an operating system that implements threads, a thread is the smallest unit that the operating system can operate on and schedule. It is included in a process, the actual unit of operation in the process, and an instance of the execution of a program is a process

A process is a running activity of a program on a data collection in a computer. It is the basic unit for resource allocation and scheduling of the system, and it is the basis of the structure of the operating system.

2 Relationship between processes and threads

Programs are compiled source code files that are stored on disk. When a program is loaded into memory by the operating system, it is a process, in which instructions and data (resources) are stored. It is also a container for threads.

Linux processes have parent, child, and windows processes are equal

Threads, sometimes referred to as lightweight processes (LWPs), are the smallest unit of program execution. A standard thread consists of a thread ID, a current instruction pointer (PC), a set of registers, and a stack

3 processes, understanding of threads

Modern operating systems propose the concept of processes, each of which regards itself as having exclusive control over all computer hardware resources. Processes are independent kingdoms and cannot freely share data between processes.
Threads are provinces. Threads within the same process can share the resources of the process, and each thread has its own separate stack.

Processes and threads in 4 python

The process starts an interpreter process, and the threads share an interpreter process

There is no relationship between the two interpreter processes. There is no casual interaction of data between different processes.
Most data runs on the main thread

Status of 4 threads

1 Overview

1 Runtime: At this point, the thread is consuming CPU resources
2 Ready state: can be converted to run state at any time because other threads are running and paused, which does not occupy CPU
3 Blocking state: Threads cannot run unless something external happens
4 Terminate: Thread complete, exit, or canceled

2 Thread State Transition

Create a process before creating a thread
Waiting for resources to run
Blocking cannot go directly into the operational state, it must go into the ready state first
Running threads can be cancelled

Two python thread development

1 Thread class

autograph

def __init__(self, group=None, target=None, name=None,
                 args=(), kwargs=None, *, daemon=None):

Parameter name and meaning:
Target:The object called by the thread is the target function
name: name the thread (different threads can have duplicate names, mainly distinguished by the thread TID)
args: Pass parameters to the target function, meta-ancestor
kwargs: Pass-in for target function keywords, dictionary

2 Instances

1 Basic Creation

Examples are as follows

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
def  test():
    for i in range(5):
        print (i)
    print ('Thread over')

# Instantiate a thread
t=threading.Thread(target=test)
t.start() # Start a thread

As the function is executed, the thread ends, the child thread does not end, the main thread always exists, and the main thread is in a waiting state

Create a thread object from threading.Thread. Target is the target function. Name can specify a name, but the thread is not started and the start method needs to be called.
Threads can execute functions because they execute code in a thread, and the simplest encapsulation is a function call.

When the function is finished, the thread exits. If you do not allow the thread to exit, you need to use a dead loop

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
def  test():
    for i in range(5):
        print (i)
    print ('Thread over')

# Instantiate a thread
t=threading.Thread(target=test,name='test1')
t.start() # Start a thread
t=threading.Thread(target=test,name='test2')
t.start() # Start a thread

# These two threads are parallel processing, or false balance if they are a CPU

give the result as follows

2 Thread Exit

There is no way for a thread to exit in python. Threads exit when
1 End of statement execution in thread function
2 Thread function throws unhandled exception

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
def  test():
    count=0
    while True:
        count+=1
        if  count==3:
            raise Exception('NUMBER')
        print (count)
# Instantiate a thread
t=threading.Thread(target=test,name='test1')
t.start() # Start a thread

Thread Exit Caused by Exception

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import  time
def  test():
    count=0
    while True:
        count+=1
        if  count==3:
            raise Exception('NUMBER')
        print (count)
def test1():
    for i in range(5):
        time.sleep(0.1)
        print ('test1',i)
# Instantiate a thread
t=threading.Thread(target=test,name='test')
t.start() # Start a thread
t=threading.Thread(target=test1,name='test1')  #Enable a thread here to see if the above threads can affect its performance
t.start()

give the result as follows

Threads in python have no priority, no concept of threadgroup, and cannot be destroyed, stopped, suspended, or resumed or interrupted. The exception to one of the threads mentioned above cannot affect the operation of another thread. The other thread runs because its function is finished

3-Thread Pass-Through

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import  time
def  test(count):
    while True:
        count+=1
        if  count==5:
            raise Exception('NUMBER')
        print (count)
# Instantiate a thread
t=threading.Thread(target=test,name='test',args=(0,))  #This must be a meta-ancestor type or an error will be reported 
t.start() # Start a thread

4 Thread Related Properties

current_thread() returns the current thread object
main_thread() returns the main thread object
Number of threads currently in alive state for active_count()
enumerate() returns a list of all live threads, excluding terminated and unstarted threads
get_ident() returns the ID of the current thread, not a zero integer

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import  time
def  test(count):
    while True:
        print ("The current thread object is{}Number of threads currently active{}".format(threading.current_thread(),threading.active_count()))
        count+=1
        if  count==5:
            break
        print (count)
    print('The list of threads currently alive is:', threading.enumerate())

# Instantiate a thread
t=threading.Thread(target=test,name='test',args=(0,))  #This must be a meta-ancestor type or an error will be reported
t.start() # Start a thread
print ('The list of threads currently alive is:',threading.enumerate())

print ('Number of threads currently active{} ,The current main thread is{},Current Thread ID by{}'.format(threading.active_count(),threading.main_thread(),threading.get_ident()))

give the result as follows

The execution of its threads is not sequential, and its calls depend on the CPU's scheduling rules, while the main thread is active until all the child threads of the child thread exit.

Properties and methods (getname and setname) for a 5-threaded instance

Name: The name of the thread, which is just an identity, can be renamed, getname() gets it, setname() sets it

ident: The thread ID, which is a non-zero integer, will not have an ID until the thread is started. Otherwise, the thread exits, the ID is still accessible and can be reused.
is_alive() returns whether the thread is alive

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import  time
def  test(count):
    while True:
        count+=1
        if  count==5:
            break
        print (count)
    print ('Current Thread name by{},ID by{}'.format(threading.current_thread().name,threading.current_thread().ident))

# Instantiate a thread
t=threading.Thread(target=test,name='test',args=(0,))  #This must be a meta-ancestor type or an error will be reported
t.start() # Start a thread
print  ('Main Thread State',threading.main_thread().is_alive())
print ('Thread state',threading.current_thread().is_alive())

give the result as follows

Differences and Connections between 3 start and run

1 Basic overview

start() Starts a thread, each thread must and can only be executed once
run() runs the thread function

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import  time
class MyThread(threading.Thread):  # Customize a class that inherits Thread's associated start and run properties
    def start(self) -> None:
        print ('start',self)
        super().start()

    def run(self) -> None:
        print ('run',self)
        super().run()
def  work():
    print ('This thread ID by{}´╝îMain Thread ID by{}'.format(threading.current_thread().ident,threading.main_thread().ident))
    print ('test')

t=MyThread(target=work,name='w')
t.start()

give the result as follows

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import  time
class MyThread(threading.Thread):  # Customize a class that inherits Thread's associated start and run properties
    def start(self) -> None:
        print ('start',self)
        super().start()

    def run(self) -> None:
        print ('run',self)
        super().run()
def  work():
    print ('This thread ID by{}´╝îMain Thread ID by{}'.format(threading.current_thread().ident,threading.main_thread().ident))
    print ('test')

t=MyThread(target=work,name='w')
t.run()

give the result as follows

The conclusion is as follows: a call to the start method results in a new thread, while a call to run is run in the main thread, and a call to run only calls its own method, while start calls itself and the run method

2 run and start call count problem

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import  time
class MyThread(threading.Thread):  # Customize a class that inherits Thread's associated start and run properties
    def start(self) -> None:
        print ('start',self)
        super().start()

    def run(self) -> None:
        print ('run',self)
        super().run()
def  work():
    print ('test')

t=MyThread(target=work,name='w')
t.start()
time.sleep(3)
t.start() #Enable threads again

As you can see above, threads call the start and run properties to run at start, and they cannot start the thread again.

Call run method

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import  time
class MyThread(threading.Thread):  # Customize a class that inherits Thread's associated start and run properties
    def start(self) -> None:
        print ('start',self)
        super().start()

    def run(self) -> None:
        print ('run',self)
        super().run()
def  work():
    print ('test')

t=MyThread(target=work,name='w')
t.run()
time.sleep(3)
t.run()

give the result as follows

run methods can only be called once

3 start with run

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import  time
class MyThread(threading.Thread):  # Customize a class that inherits Thread's associated start and run properties
    def start(self) -> None:
        print ('start',self)
        super().start()

    def run(self) -> None:
        print ('run',self)
        super().run()
def  work():
    print ('test')

t=MyThread(target=work,name='w')
t.run()
time.sleep(3)
t.start()

give the result as follows


The above results indicate that calls to run and start cannot occur on the same thread

4 Solve the call problem in the same code

Rebuild a new thread and start

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import  time
class MyThread(threading.Thread):  # Customize a class that inherits Thread's associated start and run properties
    def start(self) -> None:
        print ('start',self)
        super().start()

    def run(self) -> None:
        print ('run',self)
        super().run()
def  work():
    print ('test')

t=MyThread(target=work,name='w')
t.start()
t=MyThread(target=work,name='w1')
t.start()

give the result as follows

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import  time
class MyThread(threading.Thread):  # Customize a class that inherits Thread's associated start and run properties
    def start(self) -> None:
        print ('start',self)
        super().start()

    def run(self) -> None:
        print ('run',self)
        super().run()
def  work():
    print ('test')

t=MyThread(target=work,name='w')
t.run()
t=MyThread(target=work,name='w1')
t.run()

give the result as follows

Role of 5 run and start

Comment on inherited run methods

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import  time
class MyThread(threading.Thread):  # Customize a class that inherits Thread's associated start and run properties
    def start(self) -> None:
        print ('start',self)
        super().start()

    def run(self) -> None:
        print ('run',self)
       # super().run()
def  work():
    print ('test')

t=MyThread(target=work,name='w')
t.start()
t=MyThread(target=work,name='w1')
t.start()

give the result as follows

Disable start method

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import  time
class MyThread(threading.Thread):  # Customize a class that inherits Thread's associated start and run properties
    def start(self) -> None:
        print ('start',self)
        #super().start()

    def run(self) -> None:
        print ('run',self)
        super().run()
def  work():
    print ('test')

t=MyThread(target=work,name='w')
t.start()
t=MyThread(target=work,name='w1')
t.start()

Conclusion: The start() function calls the run function, while the run() function is used to run the function, and the start is used to create a thread. run() is necessary to execute start(), but it is not necessary to call start() when running run().

start enables new threads, which can be used to form multiple threads, while run() is a call to a function in the current thread and does not create new threads, neither of which can be called multiple times

4 Overview of multithreading

If there are multiple threads in a process, it is multithreading, which implements a concurrency

Threads are scheduled by the operating system

No new threads are opened, this is a normal function call, so t1.run() is executed, then t2.run(), which is not multithreaded

When a thread is started using the start method, multiple active threads in the process work in parallel, that is, multiple threads

There is at least one thread in a process that acts as the entry to the program. This thread is the main thread. A process has at least one main thread

Other threads are called worker threads

Threads in python have no concept of priority

5 Thread Security

This instance needs to run in ipython

The print here is interrupted with a space in the middle, which is called thread insecurity.
The print function is performed in two steps:
1 Print string
2 Line break, in between threads switch, which is not safe

Solution:

1 By splicing strings

2 Processed by logging module, the output process is uninterrupted

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import logging # Import Log Printing Module
logging.basicConfig(level=logging.INFO)  #Define base level, WARNING by default, modified to INFO here 
def woker():
    for  x  in range(10):
        msg="{} is running".format(threading.current_thread())
        logging.info(msg)  # Log Printing 
for x  in range(5):
    t = threading.Thread(target=woker,name="work-{}".format(x)).start()

give the result as follows

Use print for simple tests and log for other applications. Log printing is a technology used for log printing and cannot be interrupted.

6 daemon and non-daemon threads

1 Overview

Here the daemon thread is not a daemon in Linux

A process executes code on a thread, at least one main thread, and the other threads are worker threads
The main thread is the first to start
Parent thread: If thread B is started in thread A, A is the parent thread of B
Subthread: B is the subthread of A

In python, when building threads, you can set the daemon property, which must be set before the start method.

Related Sources

This is indicated here.If the incoming daemon is not None, it represents the default incoming value; otherwise, if it is not, it represents the daemon using the current thread

The main thread is a non-daemon thread, and daemon=False

Source for the list of live threads

This means that the list of live threads must contain the main thread.

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import logging # Import Log Printing Module
logging.basicConfig(level=logging.INFO)  #Define base level, WARNING by default, modified to INFO here
def woker():
    for  x  in range(10):
        msg="{} is running".format(threading.current_thread())
        logging.info(msg)  # Log Printing

threading.Thread(target=woker,name="work-{}".format(0)).start()
print  ('ending')
print (threading.enumerate()) #The main thread is waiting because other threads are executing

give the result as follows

2 daemon thread

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import logging # Import Log Printing Module
logging.basicConfig(level=logging.INFO)  #Define base level, WARNING by default, modified to INFO here
def woker():
    for  x  in range(10):
        msg="{} is running".format(threading.current_thread())
        logging.info(msg)  # Log Printing

threading.Thread(target=woker,name="work-{}".format(0),daemon=True).start() #The main thread typically scans the list of attributes for a certain amount of time if it has a non-daemon type
# Threads will wait for their execution to complete before exiting. If they all meet daemon-type threads, they will exit directly.
print  ('ending')
print (threading.enumerate()) #The main thread is waiting because other threads are executing

give the result as follows

The above threads are daemon threads, so the main thread will not wait for them to finish before closing

3 non-daemon and damon

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import logging # Import Log Printing Module
import time
logging.basicConfig(level=logging.INFO)  #Define base level, WARNING by default, modified to INFO here
def woker():
    for  x  in range(10):
        msg="{}  {} is running".format(x,threading.current_thread())
        logging.info(msg)  # Log Printing
        time.sleep(0.5)  #Configure the delay here to check if the non-daemon thread is finished and shuts down directly

threading.Thread(target=woker,name="work-{}".format(0),daemon=True).start() #The main thread typically scans the list of attributes for a certain amount of time if it has a non-daemon type
# Threads will wait for their execution to complete before exiting. If they all meet daemon-type threads, they will exit directly.
def woker1():
    for  x  in ['a','b','c','d']:
        msg="{}  {} is running".format(x,threading.current_thread())
        logging.info(msg)  # Log Printing

threading.Thread(target=woker1,name="work-{}".format(0)).start() #The main thread generally scans the list of attributes for a period of time and does not terminate if it has a non-daemon type.
# Here, by default, the property is taken from the parent thread, which is non-daemon, so this property will run all the time and it will close above, but it will not affect this

print  ('ending')
print (threading.enumerate()) #The main thread is waiting because other threads are executing

give the result as follows

The result indicates that when the non-daemon thread finishes execution, the main thread terminates directly and does not run again, regardless of whether damon finishes execution.

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import logging # Import Log Printing Module
import time
def woker1():
    for  x  in ['a','b','c','d']:
        msg="{}  {} is running".format(x,threading.current_thread())
        logging.info(msg)  # Log Printing

logging.basicConfig(level=logging.INFO)  #Define base level, WARNING by default, modified to INFO here
def woker():

    for  x  in range(10):
        msg="{}  {} is running".format(x,threading.current_thread())
        logging.info(msg)  # Log Printing
        time.sleep(1)  # Configure a one-second delay here so that the main thread closes without seeing the non-daemon of the grandchild thread
    T3=threading.Thread(target=woker1,name="woker{}".format(10),daemon=False)  #The thread started here defaults to a non-daemon thread, but because its parent thread is daemon
    # And here is the T1 thread below. When the T2 thread scan finds no non-daemon thread, it exits directly, and the sub-thread T3 of T1 will not continue to execute even though T3 is non-daemon.Because it is not started
    T3.start()

T1=threading.Thread(target=woker,name="work-{}".format(0),daemon=True)#The main thread typically scans the list of attributes for a certain amount of time if it has a non-daemon type
T1.start()
# Threads will wait for their execution to complete before exiting. If they all meet daemon-type threads, they will exit directly.

T2=threading.Thread(target=woker1,name="work-{}".format(0)) #The main thread generally scans the list of attributes for a period of time and does not terminate if it has a non-daemon type.
# Here, by default, the property is taken from the parent thread, which is non-daemon, so this property will run all the time and it will close above, but it will not affect this
T2.start()
print  ('ending')
print (threading.enumerate()) #The main thread is waiting because other threads are executing

give the result as follows

Maybe the grandchild thread hasn't started yet, and the main thread only sees the daemon thread.Then close it directly,

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import logging # Import Log Printing Module
import time
def woker1():
    for  x  in ['a','b','c','d']:
        msg="{}  {} is running".format(x,threading.current_thread())
        logging.info(msg)  # Log Printing

logging.basicConfig(level=logging.INFO)  #Define base level, WARNING by default, modified to INFO here
def woker():

    for  x  in range(10):
        msg="{}  {} is running".format(x,threading.current_thread())
        logging.info(msg)  # Log Printing
        # time.sleep(1)  # Configure a one-second delay here so that the main thread closes without seeing the non-daemon of the grandchild thread
    T3=threading.Thread(target=woker1,name="woker{}".format(10),daemon=False)  #The thread started here defaults to a non-daemon thread, but because its parent thread is daemon
    # And here is the T1 thread below. When the T2 thread scan finds no non-daemon thread, it exits directly, and the sub-thread T3 of T1 will not continue to execute even though T3 is non-daemon.Because it is not started
    T3.start()

T1=threading.Thread(target=woker,name="work-{}".format(0),daemon=True)#The main thread typically scans the list of attributes for a certain amount of time if it has a non-daemon type
T1.start()
# Threads will wait for their execution to complete before exiting. If they all meet daemon-type threads, they will exit directly.

give the result as follows

Or maybe the grandchild thread is up and the main thread sees the non-daemon thread and does not shut down directly, but waits for the grandchild thread to finish executing before shutting down

Related Properties

The daemon property indicates whether the thread is a daemon thread, and this value must be set before start(), otherwise an exception will be thrown
Is isDaemon() a daemon thread
setDaemon() is set to a daemon thread and must be set before the start method

Summary:

There is no direct administrative relationship between parent and child threads in python

Whether or not the main python thread kills the thread depends on daemon. If only daemon is present, all threads will be deleted and terminated by themselves. If there are any sub-threads that are non-daemon, they will wait

If you want a thread to execute completely, you need to define the non-daemon property

daemon property, must be set before start, otherwise runtimeError exception will be raised

Threads have a daemon property that can be displayed set to True or False, or not set to the default value of None
If daemon is not set, set it on the daemon of the current thread in the section

The main thread is a non-daemon thread, and daemon=False

All threads created from the main thread do not set the daemon property, and the default is daemon=False, which is the non-daemon thread

The python program is launched when there is no live non-daemon thread running, meaning that only the daemon thread is left and the main thread can exit, otherwise the main thread can wait.

Scenarios:
Do not care when to start or end with daemon, otherwise you can use non-daemon

Linux's daemon is process level, while python's daemon is thread level and there is no comparability between them

When daemon and non-daemon start up, you need to be aware of when they start up.

Simply put, there is no daemon thread. To simplify programmers'work and keep them from recording and managing background threads, the concept of daemon threads was created. The only effect of this concept is that when you set a thread as daemon, it exits with the main thread exiting.

Main scenarios:
1 Background tasks, sending heart beats, monitoring, there are more scenarios.
2 Threads that are useful only if the main thread is working, such as maintaining public resources in the main thread, the main thread has been cleaned up and is ready to exit, but it makes no sense for the worker thread to work with these resources. Exiting together is most appropriate
3 Threads that can be terminated at any time

7 join

Join is one of the standard threading functions that means wait, who calls join, who waits

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import logging # Import Log Printing Module
import time
def  foo(n):
    for i in range(n):
        print (i)
        time.sleep(0.5)
t1=threading.Thread(target=foo,args=(10,),daemon=True)
t1.start()  # By default, this thread can only execute a small amount of this, generally not all of it
t1.join()  # The thread execution that could not have been completed was completed by the join method

give the result as follows

With the join method, the daemon thread does not exit until execution is complete.

join(timeout=None) is one of the standard methods for threads.
The timeout parameter specifies how long the caller waits without setting a timeout, and then waits until the end of the called thread. Whose join method is called is who joins and who waits.

The join method of another thread is called in one thread, and the caller is blocked until the callee thread terminates. A thread can be joined more than once

If a join method is used on another daemon thread D in one daemon C thread, it only means that C waits for D, the main thread exits, C and D end or not, and that whoever they wait for will be killed.

8 threading.local class

python provides a threading.local class that instantiates this to a global object, but with different threads, the data stored in this object is not visible to other threads

1 Local variable

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import time
def  worker():
    x=0  # Here is a local variable
    for i in range(10):
        time.sleep(0.0001)
        x+=1
    print (threading.current_thread(),x)
for i in range(10):
    threading.Thread(target=worker).start()

give the result as follows

2 Global variables

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import time
x = 0  # Here is a global variable
def  worker():
    for i in range(10):
        global x
        time.sleep(0.0001)
        x+=1
    print (threading.current_thread(),x)
for i in range(10):
    threading.Thread(target=worker).start()

give the result as follows

Local variables themselves are isolated, and once they become global, all threads will be able to access and modify them.

3 Use class processing

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import time
class  A:
    def __init__(self,x):
        self.x=x
a=A(0)
def  worker():
    for i in range(100):
        a.x=0
        time.sleep(0.0001)
        a.x+=1
    print (threading.current_thread(),a.x)
for i in range(10):
    threading.Thread(target=worker).start()

give the result as follows

The TIDs of different threads are different, and can be keyed by TIDs of different threads. The resultant value resolves this confusion.

4 threading.local

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import time
a=threading.local()  # Isolate data by TID to handle different numerical problems for different threads
def  worker():
    a.x = 0
    for i in range(100):
        time.sleep(0.0001)
        a.x+=1
    print (threading.current_thread(),a.x)
for i in range(10):
    threading.Thread(target=worker).start()

give the result as follows

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import time
a=threading.local()  # Isolate data by TID to handle different numerical problems for different threads
def  worker():
    a.x = 0
    for i in range(100):
        time.sleep(0.0001)
        a.x+=1
    print (threading.current_thread(),a.x)
    print (threading.get_ident(),a.__dict__) #Thread TID s and dictionaries are printed here
for i in range(10):
    threading.Thread(target=worker).start()

give the result as follows

5 Source Code


self.key is preceded by id
Through a dictionary, the address of the thread ID is unique, but the thread ID across processes is not necessarily the same

Thread addresses in the process may be the same.Each process considers itself an exclusive resource, but not necessarily.

6 Practices

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import time
X='abc'
ctx=threading.local()
ctx.x=123
def work():
    print (X)
    print (ctx)
    print (ctx.x)  #CTX This ctx.x property in the dictionary at this time, so it cannot be printed, it is inside the thread, and the corresponding value for each dict is independent
    print ('end')
threading.Thread(target=work).run()  # This is a local thread call, it will not affect
threading.Thread(target=work).start()

give the result as follows

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import time
X='abc'
ctx=threading.local()
ctx.x=123
def work():
    print (X)
    print (ctx)
    ctx.x=100 #Defining a local variable in an internal thread allows execution and invocation
    print (ctx.x)  #ctx does not have this property at this time, so it cannot print. It is inside a thread.
    print ('end')
threading.Thread(target=work).run()  # This is a local thread call, it will not affect
threading.Thread(target=work).start()

give the result as follows

7 Conclusion

The threading.local class component consists of a large dictionary whose address of each thread instance of the element is a map (stack) of Key and the thread's reference thread's separate dictionary. Theading.local instances allow you to safely use thread-specific data in different threads, isolating data between threads as if they were local changesSame amount

8 Delayed execution of Timter

1 Source

As you can see above, the first field is time.

2 Basic Instances

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import datetime
start_time=datetime.datetime.now()

def  add(x,y):
    print   (x+y)
    print("Function execution time is{}".format((datetime.datetime.now() - start_time).total_seconds()))

t=threading.Timer(3,add,args=(3,4))
t.start()  #3 seconds delay here

give the result as follows

Here is the delayed execution thread, not the delayed execution function, essentially the thread

3 t.cancel() thread deletion

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import datetime
import time
def  add(x,y):
    print   (x+y)
t=threading.Timer(6,add,args=(3,4)) # This means the result will be in 6 seconds
t.start()
time.sleep(5) 
t.cancel() #Thread deleted

Threads that do not actually execute can be cancel ed

#!/usr/bin/poython3.6
#conding:utf-8
import  threading
import datetime
import time
def  add(x,y):
    time.sleep(5)
    print   (x+y)
t=threading.Timer(6,add,args=(3,4)) # This means the result will be in 6 seconds
t.start()
time.sleep(10)
t.cancel()

give the result as follows

After the start method, the timer object is in a waiting state, and after waiting for the interval, the function function is executed, and if the cancel method is used before the function is executed, the end of the function is skipped.
cancel has no effect if the thread has already started executing

4 Summary

Timer is a subclass of Thread threads, which are threaded classes with the capabilities and characteristics of threads
An instance of this is a thread that can delay the execution of the target function, and it can be cancel ed before the target function is actually executed.

Tags: Programming Python Linux RabbitMQ kafka

Posted on Tue, 13 Aug 2019 18:20:22 -0700 by Silverlime