Let's study Python

Python threading allows for parallel execution of tasks, enhancing program performance.

# Python Threading and `stack_size` Usage

Threading in Python is a technique used for performing multiple tasks concurrently. By using threading, multiple tasks can be processed in parallel, which helps in improving the performance of a program. The `threading` module in Python is used to create and manage threads.

## Definition
Threading in Python is used to perform multiple tasks simultaneously. Threads in Python are independent operations that can run concurrently, enhancing the program’s performance. Each thread has its own goal, and when multiple threads are running, it is referred to as multithreading.

## Usage
To use threading in Python, you need to import the `threading` module:
“`python
import threading
“`

To create a thread and specify the task it will perform, you can follow these steps:
1. Define the function that the thread will execute.
2. Create the thread object and pass the function along with any required arguments.
3. Start the thread to execute the specified function.

Example:
“`python
import threading

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

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

Another example showing parallel execution of tasks using threading:
“`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()
“`

## Daemon Threads
Daemon threads in Python are auxiliary threads that assist the main threads in performing tasks. They automatically terminate when the main thread exits. Daemon threads are suitable for tasks related to the application’s lifecycle, such as automatic saving, garbage collection, file monitoring, and session monitoring.

Example illustrating the usage of 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.2, ‘일반직원’))
thread_1.start()

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

## Threading Advantages and Disadvantages
### Advantages
– Enhances program performance by parallel execution of tasks.
– Saves time by processing multiple tasks simultaneously.
– Allows non-blocking execution of tasks in different threads.
### Disadvantages
– Synchronization issues may arise when multiple threads access the same resource.
– Managing threads can be complex, considering priorities, states, etc.
– Thread creation and management may lead to overhead due to system resource consumption.

## Thread Objects
Thread objects in Python provide functionalities to work with threads. Some important methods and attributes of Thread objects include:
– `start()`: Initiates the thread’s activity.
– `run()`: Represents the thread’s activity and can be overridden in subclasses.
– `join(timeout=None)`: Waits for the thread to complete its task.
– `name`: A string used for identification purposes.
– `is_alive()`: Checks if the thread is alive.
– `daemon`: Indicates whether the thread is a daemon thread.
– `ident`: Thread’s identifier (integer value).
– `get_native_id()`: Returns the native integer thread ID.

## Fork and Join
– **Fork**: Refers to the main thread creating sub-threads.
– **Join**: Waits for all threads to finish their tasks. Used when data processed by multiple threads needs to be collected before further sequential processing.

Example demonstrating Fork and Join in Python threading:
“`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”)
t1 = Worker(“1”)
t1.start()

t2 = Worker(“2”)
t2.start()

t1.join()
t2.join()

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

In this example, the main thread waits for threads `t1` and `t2` to finish before executing post-job tasks.

References:
– [Python Documentation on Threading](https://docs.python.org/ko/3.9/library/threading.html)
– [Understanding Python Threading](https://miki3079.tistory.com/50)
– [Threading in Python Explained](https://mechacave.tistory.com/2)
– [Daemon Threads Explanation](https://sharonprogress.tistory.com/324)
– [Python Threading Tutorial](https://wikidocs.net/82581)