Let's study Python

Unlock the power of parallel processing with Python Threading!

Python Threading – How to Use threading.settrace

## Overview
In Python, threading is a technique used to perform multiple tasks simultaneously. Threading allows multiple tasks to be executed in parallel, enhancing the performance of a program. The threading module in Python is used to create and manage threads.

### Definition
Threading in Python refers to the technology used to perform multiple tasks concurrently. It enables tasks to be processed in parallel, thereby improving the program’s performance. In Python, the threading module is utilized to create and manage threads. A thread is an independent operation that runs concurrently with other threads, and when multiple threads are operating, it is referred to as multithreading.

### Usage
To use threading in Python, the threading module must be imported. Tasks are specified, and necessary information is passed to create a thread using the following steps:
1. Import the threading module:

“`python
import threading
“`

2. Define the task and pass required arguments:

“`python
thread_1 = threading.Thread(target=my_function, args=(required_arguments))
“`

3. Start the thread:

“`python
thread_1.start()
“`

### Examples
Here are some examples of using threading in Python:

#### Example 1: Basic Thread Execution
“`python
import threading

def my_function():
print(“Hello, I’m running in a thread!”)

thread = threading.Thread(target=my_function)
thread.start()
“`

#### Example 2: Performing Tasks in Parallel
“`python
import threading

def print_numbers():
for i in range(1, 11):
print(i)

def print_letters():
for letter in ‘abcdefghij’:
print(letter)

thread1 = threading.Thread(target=print_numbers)
thread2 = threading.Thread(target=print_letters)
thread1.start()
thread2.start()
“`

#### Example 3: Using Threads for Different Roles
“`python
import threading
import time

def doingJob(jobs, delay, name):
print(f”{name} 님에게 {jobs}개의 일이 주어졌습니다.

\n”)
for i in range(jobs):
print(f”{name} 님이 {i+1}번 째 일을 완료하였습니다.

“)
time.sleep(delay)
print(f”{name} 님이 일을 마치고 퇴근합니다.

\n”)

thread_1 = threading.Thread(target=doingJob, args=(5, 0.2, ‘일반직원’))
thread_1.start()

doingJob(3, 0.1, ‘사장’)
“`

### Daemon Threads
Daemon threads in Python are auxiliary threads that help in the execution of primary threads. They automatically terminate when the main thread finishes. Daemon threads are suitable for tasks related to the application’s lifecycle, such as auto-saving, garbage collection, file monitoring, and session monitoring.

#### Example: Using Daemon Threads
“`python
import threading
import time

def doingJob(jobs, delay, name):
print(f”{name} 님에게 {jobs}개의 일이 주어졌습니다.

\n”)
for i in range(jobs):
print(f”{name} 님이 {i+1}번 째 일을 완료하였습니다.

“)
time.sleep(delay)
print(f”{name} 님이 일을 마치고 퇴근합니다.

\n”)

thread_1 = threading.Thread(target=doingJob, args=(5, 0.1, ‘일반직원’))
thread_1.start()

thread_2 = threading.Thread(target=doingJob, args=(10, 0.1, ‘관리직원’))
thread_2.daemon = True
thread_2.start()

doingJob(3, 0.1, ‘사장’)
“`

### Advantages and Disadvantages of Threading
#### Advantages
– Enhances program performance by executing tasks in parallel.
– Allows for time-saving by processing multiple tasks concurrently.
– Enables non-blocking execution of tasks in different threads.

#### Disadvantages
– Synchronization issues can arise when multiple threads access the same resource simultaneously.
– Thread management can be complex, considering thread priorities and states.
– Overhead may occur when creating and managing threads, leading to system resource consumption.

### Types of Threads in Python
Python provides various types of threads for different purposes. Some of the commonly used thread-related functions include:
– `threading.active_count()`
– `threading.current_thread()`
– `threading.enumerate()`
– `threading.settrace(func)`
– `threading.setprofile(func)`

### Thread Objects
Thread objects in Python represent individual threads and provide methods to control and interact with threads. Some essential methods of Thread objects are:
– `start()`
– `run()`
– `join(timeout=None)`
– `is_alive()`
– `daemon`
– `name`

### Fork and Join
Forking involves the main thread creating sub-threads, while joining refers to waiting for all threads to finish their tasks before proceeding further. Join is commonly used when multiple threads process data in parallel, and the main thread needs to consolidate the results.

#### Example: Fork and Join in Python
“`python
import threading
import time

class Worker(threading.Thread):
def __init__(self, name):
super().__init__()
self.name = name

def run(self):
print(“Sub thread start”, threading.currentThread().getName())
time.sleep(5)
print(“Sub thread end”, threading.currentThread().getName())
print(“Main thread start”)

threads = []
for i in range(3):
thread = Worker(i)
thread.start()
threads.append(thread)

for thread in threads:
thread.join()

print(“Main thread post job”)
print(“Main thread end”)
“`

In this example, the main thread waits for the sub-threads to complete their tasks before proceeding. Using join ensures synchronization among multiple threads.

### Sources
– [Understanding Python Threading – Miki’s Blog](https://miki3079.tistory.com/50)
– [Threading in Python – Mechacave](https://mechacave.tistory.com/2)
– [Daemon Threads Explanation – Sharon Progress](https://sharonprogress.tistory.com/324)
– [Python Threading Documentation](https://docs.python.org/ko/3.9/library/threading.html)
– [Threading in Python – WikiDocs](https://wikidocs.net/82581)

By following the guidelines and examples provided above, you can effectively utilize threading in Python to enhance the performance and efficiency of your programs.