多线程-互斥锁或死锁

1.简单的多线程:

import threading
import time
def say(name):
    print('%s 子线程 start ' % name)
    time.sleep(10)
    print('%s 子线程 stop'%name)
    global a
    a='chenwei'

if __name__=='__main__':
    print('___主线程开始___')
    t = threading.Thread(target=say,args=('eve',))
    t.setName("线程的名字")
    t.setDaemon(True)#把主线程设置为守护线程(默认为False),若主线程结束了_不管子线程是否执行完成都会一并与主线程退出(必须在start执行使用setDaemon)
    aa=t.start()
    print('___主线程先走一步___')
    print(t.getName())#获取线程名字
    #t.join()#等待子线程执行结束后,在执行主线程,,也可以设置超时时间join(3)
    print('___主线程结束___')
    
    '''
    t.setDaemon(True)#把主线程设置为守护线程(默认为False),若主线程结束了_不管子线程是否执行完成都会一并与主线程退出(必须在start执行使用setDaemon)
    t.setDaemon(False)#主线程执行不会等待子线程,当主线程执行完毕后会等待子线程
    '''

 

2.多线程-死锁:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import threading
import time
#———————————————————————————————多线程-互斥锁或死锁————————————————————————————————————————
chen=1
num = 0
def run(n):
    global num
    suo1=nutex.acquire()#上锁1(上锁后资源被锁定,其他线程用不了)
    if suo1:
        print('锁1存在')
        nutex.release()#解锁1(上锁前需要前解开)
        #当在一个锁的内部创建另外一个锁,而原来的锁没有解开就会死锁(程序执行到内锁就僵死了)
        suo2=suo.acquire()#上锁2
        if suo2:
            print('锁2存在')
            for i in range(1000000):
                num += 1
        #suo.release()#解锁2(若不解锁suo,那么线程2将会变成死锁,程序将卡死)
    print ("num1:", num)

def test(m):
    global num
    suo.acquire()#上锁(当上一个锁被解开后才能上锁)
    for i in range(1000000):
        num += 1
    suo.release()#解锁
    print ("num2:", num)
#创建两把锁
nutex=threading.Lock()#创建锁对象
suo=threading.Lock()#创建锁对象
t = threading.Thread(target=run, args=('a',))#这是随便传的值
t.start()
t = threading.Thread(target=test, args=('b',))#这是随便传的值
t.start()
#t.join()
print ("num:", num)

 

3.在主线程中直接终止子线程:

#!/usr/bin/env python
# encoding: utf-8

import threading
import time
import sys
import ctypes
import inspect



def say(name):
    print('%s 子线程 start ' % name)
    time.sleep(5)
    print('%s 子线程 stop'%name)
    global a
    a='chenwei'



def __async_raise(thread_Id, exctype):
    #在子线程内部抛出一个异常结束线程
    #如果线程内执行的是unittest模块的测试用例, 由于unittest内部又异常捕获处理,所有这个结束线程
    #只能结束当前正常执行的unittest的测试用例, unittest的下一个测试用例会继续执行,只有结束继续
    #向unittest中添加测试用例才能使线程执行完任务,然后自动结束。
    thread_Id = ctypes.c_long(thread_Id)
    if not inspect.isclass(exctype):
        exctype = type(exctype)
    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_Id, ctypes.py_object(exctype))
    if res == 0:
        raise ValueError("invalid thread id")
    elif res != 1:
        ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_Id, None)
        raise SystemError("PyThreadState_SEtAsyncExc failed")


def terminator(thread):
    #结束线程
    __async_raise(thread.ident, SystemExit)




if __name__=='__main__':
    print('___主线程开始___')
    t = threading.Thread(target=say,args=('eve',))
    t.setName("thread_01")#设置子线程名字
    t.start()#启动子线程
    print('___主线程先走一步___')
    print(t.getName())#获取线程名字
    #t.join()#等待子线程执行结束后,在执行主线程,,也可以设置超时时间join(3)

    terminator(t)#在主线程中直接终止子线程

    print('___主线程结束___')

 

4.子线程制造数据给主线程:

#!/usr/bin/env python
# encoding: utf-8
import time
import ctypes
import inspect
import random
import threading
###_____________________________________________子线程制造数据给主线程__________________________________________________________
'''
应用场景:主线程在android设备上执行业务操作、子线程需要记录android设备的cpu、内存等信息,在主线程执行后需要子线程的监控数据
'''

def __async_raise(thread_Id, exctype):
    #在子线程内部抛出一个异常结束线程
    #如果线程内执行的是unittest模块的测试用例, 由于unittest内部又异常捕获处理,所有这个结束线程
    #只能结束当前正常执行的unittest的测试用例, unittest的下一个测试用例会继续执行,只有结束继续
    #向unittest中添加测试用例才能使线程执行完任务,然后自动结束。
    thread_Id = ctypes.c_long(thread_Id)
    if not inspect.isclass(exctype):
        exctype = type(exctype)
    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_Id, ctypes.py_object(exctype))
    if res == 0:
        raise ValueError("invalid thread id")
    elif res != 1:
        ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_Id, None)
        raise SystemError("PyThreadState_SEtAsyncExc failed")

def terminator(thread):
    #结束子线程
    __async_raise(thread.ident, SystemExit)



chen=[]#接收子线程制造的数据
def say(name):
    print('%s 子线程 start ' % name)
    time.sleep(2)
    print('%s 子线程 stop'%name)
    while True:
        time.sleep(2)
        number=random.randint(10,100)#随机数
        print('子线程循环中...........')
        chen.append(number)




if __name__=='__main__':
    print('___主线程开始___')
    t = threading.Thread(target=say,args=('eve',))
    t.setName("thread_01")#设置子线程名字
    t.start()#启动子线程
    print('___主线程先走一步___')
    print('子线程的名字:',t.getName())#获取线程名字
    #t.join()#等待子线程执行结束后,在执行主线程,,也可以设置超时时间join(3)

    #主线程
    for i in range(10):
        time.sleep(3)
        print('主线程执行中,使用循环代替执行操作{}'.format(i))
    terminator(t)#在主线程中直接终止子线程
    print('chen的值为:',chen)
    print('___主线程结束___')

 

 5.终止子线程的方法:

#!/usr/bin/env python
# encoding: utf-8

import os
import time
import threading
import threading,time
'''
这里重点介绍一下第二种方法,某些时候第一种方法不适用,会报错。例如开了一个线程,在线程内部又开了一个线程,此时关闭第一个线程就会报如下错误。

raise ValueError("invalid thread id")
ValueError: invalid thread id
'''

#________________________________________________________________________方法一_________________________________________________________
def stop_thread(thread):
    import inspect
    import ctypes
    tid = thread.ident
    exctype = SystemExit
    """raises the exception, performs cleanup if needed"""
    tid = ctypes.c_long(tid)
    if not inspect.isclass(exctype):
        exctype = type(exctype)
    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
    if res == 0:
        raise ValueError("invalid thread id")
    elif res != 1:
        # """if it returns a number greater than one, you're in trouble,
        # and you should call it again with exc=NULL to revert the effect"""
        ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
        raise SystemError("PyThreadState_SetAsyncExc failed")


def serial_read(delay):
    while(1):
        time.sleep(delay)
        print('111')
    pass

try:
    myThread = threading.Thread(target=serial_read,args=(1,))
    myThread.start()
except:
    print('error')

print('222')
time.sleep(10)
stop_thread(myThread)




#_____________________________________________________________________________________________方法二___________________________________________________________________
class StoppableThread(threading.Thread):
    def __init__(self,  *args, **kwargs):
        super(StoppableThread, self).__init__(*args, **kwargs)
        self._stop_event = threading.Event()

    def stop(self):
        self._stop_event.set()

    def stopped(self):
        return self._stop_event.is_set()


    def run(self):
        print("{}开始运行子线程....".format(os.getpid()))
        while True:
            print("子线程循环等待.....")
            time.sleep(1)
            if self.stopped():
                # 做一些必要的收尾工作
                break


if __name__ == "__main__":
    print("开始运行主线程..........")
    t = StoppableThread()
    t.start()
    time.sleep(10)
    t.stop()#主动停止子线程
    #t.join()#等待子线程结束后在执行主线程
    print("主线程停止运行")




#___________________________________________________________________方法三___________________________________________________________________________
import threading
import inspect
import ctypes
import time

def _async_raise(tid, exctype):
    if not inspect.isclass(exctype):
        raise TypeError("Only types can be raised (not instances)")
    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid,ctypes.py_object(exctype))
    if res == 0:
        raise ValueError("invalid thread id")
    elif res != 1:
        ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0)
        raise SystemError("PyThreadState_SetAsyncExc failed")


class ThreadWithExc(threading.Thread):
    def _get_my_tid(self):

        if not self.isAlive():
            raise threading.ThreadError("the thread is not active")

        if hasattr(self, "_thread_id"):
            return self._thread_id

        for tid, tobj in threading._active.items():
            if tobj is self:
                self._thread_id = tid
                return tid

        raise AssertionError("could not determine the thread's id")

    def raiseExc(self, exctype):
        _async_raise(self._get_my_tid(), exctype )

def work():
    try:
        while True:
            print('子线程work...........')
            time.sleep(1)
    except Server.ThreadStopped:
        pass
    print('子线程退出............')




class Server:
    class ThreadStopped(Exception): pass
    def __init__(self):
        self.thread = ThreadWithExc(target=work)

    def start(self,device,name):
        self.thread.start()

    def stop(self):
#        _async_raise(self.thread.raiseExc(TypeError))
        self.thread.raiseExc(self.ThreadStopped)



if __name__ == '__main__':
    print('主线程开始........')
    server = Server()
    server.start('chenwei','123456789')
    for i in range(10):
        print('主线程循环等待中..........')
        time.sleep(1)
    server.stop()

 

 6.多进程操作接口

import requests
import json
from concurrent.futures import ThreadPoolExecutor

def delete(id):
    url = "https://pet-im-app-server.bndxqc.com/label/delete-label"
    payload = json.dumps({"id": id})
    headers = {
           'Authorization': 'Bearer eyJhbGciOiJhn2B5y7JtxM',
           'Tenantid': '2951baabc1c442cf901402bd0a34d682',
           'Content-Type': 'application/json',
           'Accept': '*/*',
           'Host': 'pet-im-app-server.bndxqc.com',
           'Connection': 'keep-alive'
        }

    response = requests.post(url, headers=headers, data=payload)
    return response.text  # 返回响应内容

def worker(idlist, max_workers=4):
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        # 使用executor.map并行执行delete函数
        futures = executor.map(delete, idlist)
        for future in futures:
            print(future)  # 打印每个响应内容


#需要操作的id idlist = idlist=[ "d016d149-f173-45ed-b298-9b14c87ad10f", "e38d599b-d4b9-4057-aa40-b0feb73f36c8", "e6801319-4d43-4d52-a164-3933c2ff021e", "e70d74c8-b3a4-42b0-aeb5-f4d8059018b9", "e7818b88-0a05-4884-a8e5-55d8e37090d9", "e8257439-2402-4a00-be62-ad464127301f", "e854a74a-f7dc-4b61-90a7-7c0e090a2835", "ea65e1ec-dd93-4244-a81a-c070a3256011", "ead1af14-90be-46de-a05f-cd10bbe36bd9", "a2856cd9-c37f-4a07-b295-c64e44eb4c7b" ] # 启动多线程工作 worker(idlist) delete(idlist)

 

 

 

 

相关连接:

https://zhuanlan.zhihu.com/p/336289766 ......................................................................................................Python中的并发与并行

https://www.cnblogs.com/v3ucn/p/16542155.html .........................................................................................多线程threading/多进程multiprocessing/协程asyncio

 

posted on 2019-08-01 19:18  chen_2987  阅读(129)  评论(0编辑  收藏  举报

导航