线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体。程序是指令、数据及其组织形式的描述,进程是程序的实体。
Threads share the address space of the process that created it; processes have their own address space.
线程的地址空间共享,每个进程有自己的地址空间。
Threads have direct access to the data segment of its process; processes have their own copy of the data segment of the parent process.
一个进程中的线程直接接入他的进程的数据段,但是每个进程都有他们自己的从父进程拷贝过来的数据段
Threads can directly communicate with other threads of its process; processes must use interprocess communication to communicate with sibling processes.
一个进程内部的线程之间能够直接通信,进程之间必须使用进程间通信实现通信
New threads are easily created; new processes require duplication of the parent process.
新的线程很容易被创建,新的进程需要从父进程复制
Threads can exercise considerable control over threads of the same process; processes can only exercise control over child processes.
一个进程中的线程间能够有相当大的控制力度,进程仅仅只能控制他的子进程
Changes to the main thread (cancellation, priority change, etc.) may affect the behavior of the other threads of the process; changes to the parent process does not affect child processes.
改变主线程(删除,优先级改变等)可能影响这个进程中的其他线程;修改父进程不会影响子进程
创建线程
def Cycle_number5():
for number in range(5):
print(number)
time.sleep(1)
def Cycle_number10():
for number in range(10):
print(number)
time.sleep(1)
def start_thread():
thread1 = threading.Thread(target=Cycle_number5)
thread2 = threading.Thread(target=Cycle_number10)
thread1.start()
thread2.start()
print(threading.enumerate())
通过类创建线程,修改类中的run函数
class new_Thread(threading.Thread):
def run(self):
for i in range(3):
time.sleep(1)
msg = "I'm" + self.name + '@' + str(i)
print(msg)
self.print_name()
def print_name(self):
time.sleep(1)
print(self.name)
instance1 = new_Thread()
instance2 = new_Thread()
instance1.start()
instance2.start()
在函数里声明全局变量,来改变变量值
number = 100
numbers = [11, 22]
def add100():
global number
number += 100
def add10():
global number
number += 10
def append33():
numbers.append(33)
print (number)
print (numbers)
add100()
add10()
append33()
print (number)
print (numbers)
多线程共用全局变量
global_number = 100
def add1():
global global_number
global_number += 1
print("global_number = %d" %global_number)
def add2():
global global_number
global_number += 2
print('global_number = %d' %global_number)
def add3():
global global_number
global_number += 3
print('global_number = %d' %global_number)
instance1 = threading.Thread(target=add1)
instance2 = threading.Thread(target=add2)
instance3 = threading.Thread(target=add3)
instance1.start()
instance2.start()
instance3.start()
print('---in main Thread g_num = %d---' %global_number)
全局变量传递参数
def append33(g_nums):
g_nums.append(33)
print("---g_num = %s" % str(g_nums))
def append22(g_nums):
g_nums.append(22)
print('--- g_num = %s---' % str(g_nums))
global_nums = [11, 22]
inst1 = threading.Thread(target=append33, args=(global_nums,))
inst2 = threading.Thread(target=append22, args=(global_nums,))
inst1.start()
inst2.start()
print('---in main Thread g_num = %s---' % str(global_nums))
资源竞争
g_num = 0
def a_cycle_add1(cycle_num):
global g_num
for i in range(cycle_num):
g_num += 1
print("--- g_num = %d" %g_num)
def b_cycle_add1(cycle_num):
global g_num
for i in range(cycle_num):
g_num += 1
print('--- g_num = %d---' %g_num)
instance1 = threading.Thread(target=a_cycle_add1,args=(1000000,))
instance2 = threading.Thread(target=b_cycle_add1,args=(1000000,))
instance1.start()
instance2.start()
print('---in main Thread g_num = %d---' %g_num)
全局解释器锁来说,就是在CPython上面才有的,它的原理是在解释器层面加上一把大锁,保证同一时刻只能有一个python线程在解释器中执行。
I/O密集型的python多线程进程,每个线程在等待I/O的时候,将会释放GIL资源,供别的线程来抢占。所以对于I/O密集型的python多线程进程来说,还是能比顺序执行的效率要高的。
互斥(mutex)锁:
当多个线程修改同一个数据的时候,如果操作的时间够短的话,能得到我们想要的结果,但是,如果修改数据不是原子性的(这中间的时间太长)的话。。。很有可能造成数据的错误覆盖,从而得到我们不想要的结果。
g_num = 0
def a_cycle_add1(cycle_num):
global g_num
for i in range(cycle_num):
mutex.acquire()
g_num += 1
mutex.release()
print(" in a g_num = %d" %g_num)
def b_cycle_add2(cycle_num):
global g_num
for i in range(cycle_num):
mutex.acquire()
g_num += 1
mutex.release()
print(' g_num = %d---' %g_num)
mutex = threading.Lock()
instance1 = threading.Thread(target=a_cycle_add1,args=(1000000,))
instance2 = threading.Thread(target=b_cycle_add2,args=(1000000,))
instance1.start()
instance2.start()
print('---in main Thread g_num = %d---' %g_num)
https://www.cnblogs.com/huxianglin/p/5973471.html
def recvfrom(udp_socket):
while True:
recv_data = udp_socket.recvfrom(1024)
print(recv_data)
def sendto(udp_socket, dest_ip, dest_port):
while True:
send_data = input("请输入要发送的数据:")
udp_socket.sendto(send_data.encode('utf-8'),(dest_ip,dest_port))
def main():
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udp_socket.bind(('',7890))
dest_ip = input('输入对方的ip:')
dest_port = int(input(" 请输入对方的port: "))
t_recv = threading.Thread(target=recvfrom,args=(udp_socket,))
t_send = threading.Thread(target=sendto,args=(udp_socket, dest_ip, dest_port))
t_recv.start()
t_send.start()
if __name__ == "__main__":
main()