嘉兴网站建设的前景,牌子网官网,上海好的高端网站建,公司实验室设计一.死锁的问题
原因#xff1a;多个进程或线程共享资源造成的一种僵持状态#xff1a;1.竞争系统资源#xff1b;2.进程的推进顺序不当#xff1b; 产生的必要条件#xff1a;1.互斥条件#xff1b;2.请求和保持条件#xff1b;3.不可剥夺条件#xff1b;4.环路等待条…一.死锁的问题
原因多个进程或线程共享资源造成的一种僵持状态1.竞争系统资源2.进程的推进顺序不当 产生的必要条件1.互斥条件2.请求和保持条件3.不可剥夺条件4.环路等待条件 解决死锁 预防死锁通过有序的资源配置足够的资源分配 解决死锁强行剥夺资源撤销进程等
二.线程间通信
1.通信方式
信号槽通信 Qt特有的通信方式可在类之间线程之间进行信息交互或通信 共享变量 最常用的方式对于一些全局变量多个线程同时操作需要用原子变量或者用互斥锁临界区等多线程同步解决线程安全问题 自定义消息 借助于windows程序的消息通信机制当两个线程之间至少有一个为UI线程那么就可以直接通过SendMessage或者PostMessage来发送消息到指定线程进行响应。这种方法涉及到线程的切换如果SendMessage/PostMessage指定的窗口是由调用线程创建那么就是一个普通的子程序如果指定窗口由另一个线程创建也即UI线程那么系统会挂起当前工作线程切换到ui线程并调用合适的窗口过程(PostMessage则直接进消息队列 promise、future语法 promise对象通过promise.get_future()函数和future对象联系起来promise对象通过set_value设置值而future对象通过get获取值。这在两个不同线程内也可以执行。在get没有获取值值之前该线程被阻塞。这里的T是任意类
2.通信安全
1临界区 通过对多线程的串行化来访问公共资源或一段代码速度快适合控制数据访问。EnterCriticalSection 进入临界区LeaveCriticalSection 离开临界区EnterCriticalSection 2互斥锁 为协调共同对一个共享资源的单独访问而设计互斥量跟临界区很相似只有拥有互斥对象的线程才具有访问资源的权限由于互斥对象只有一个所以任何情况下此共享资源都不会同时被多个线程所访问。互斥量比临界区复杂。因为使用互斥不仅可以在多线程中实现资源的安全共享而且可以在不同多进程之间实现对资源的安全共享。CreateMutex 创建一个互斥量OpenMutex 打开一个互斥量ReleaseMutex 释放互斥量WaitForMultipleObjects 等待互斥量对象 3原子变量 通过原子操作给原子类型指定bool、char、int、long、指针等类型作为模板参数原子是不可被CPU上下文交换的机器指令这些指令组合在一起就形成了原子操作。在多核CPU下当某个CPU核心开始运行原子操作时会先暂停其它CPU内核对百年来所在内存的操作以保证原子操作不会被其它CPU内核所干扰其内部使用CAS循环所以无需加锁即可实现线程安全。 4信号量 信号量对象对线程的同步方式互斥锁临界区等方法不同信号允许多个线程同时使用共享资源 只限制访问共享资源的线程最大数目。信号量操作函数CreateSemaphore 创建一个信号量OpenSemaphore 打开一个信号量ReleaseSemaphore 释放信号量WaitForSingleObject 等待信号量 事件Event 事件对象也可以通过通知操作的方式来保持线程的同步。并且可以实现不同进程中的线程同步操作。事件的几个函数CreateEvent 创建一个事件OpenEvent 打开一个事件SetEvent 回置事件WaitForSingleObject 等待一个事件 join函数 通过C11新特性的join函数来进行线程的流程控制管理对线程进行阻塞确保线程安全
3.Qt中多线程使用
创建继承自Qthread的子类重写父类的Run方法实现子线程要处理的业务再用start启动方法。优点代码实现简单但在一个子线程中处理多个任务所有的处理逻辑都需要写到run()函数中这样该函数中的处理逻辑就会变得非常混乱不太容易维护 从QObject派生一个普通的工作类添加成员函数来实现子线程要处理的业务逻辑在主线程中创建QThread对象和前面的工作类对象通过moveToThread()将工作对象移动到创建的子线程对象中调用start()启动子线程最后手动调用工作类对象的对应函数即可真正在让其在子线程中执行。优点可以创建多个类似的工作类将各自的业务流程作为成员函数然后将这个业务类的实例对象移动到对应的子线程中moveToThread()就可以了这样可以让编写的程序更加灵活。 使用Qt的线程池线程池其实由三部分组成任务队列工作的线程管理者线程。Qt中的 QThreadPool 类管理了一组 QThreads, 里边还维护了一个任务队列。QThreadPool 管理和回收各个 QThread 对象以帮助减少使用线程的程序中的线程创建成本。每个Qt应用程序都有一个全局 QThreadPool 对象可以通过调用 globalInstance() 来访问它。也可以单独创建一个 QThreadPool 对象使用
4.VS中多线程使用
MFC中使用AfxBeginThread来创建线程该函数使用完后会自动释放掉线程句柄 WinAPI中使用CreateThread来创建线程CreateThread 和CloseHandle是成对的程序是不会自动释放线程句柄。在不用时需要调用CloseHandle函数释放线程句柄 C11中的std::thread线程类实现多线程其构造函数会立即启动线程并且线程的生命周期与std::thread对象绑定。因此在使用std::thread时不需要显式调用类似start的方法
三.进程间通信
1.通信方式
1共享文件模式 通过多个进程共同读写同一个文件来实现通信如管理多个进程的配置文件CFile的read()write() 2映射文件模式 通过两个或多个进程映射同一个文件映射对象的视图来实现的CreateFileMapping(),OpenFileMapping(),MapViewOfFile(),UnmapViewOfFile(); 3共享内存模式 通过多个进程来调用操作原始内存的模式实现ReadProcessMemory()和WriteProcessMemory() 4管道方式 管道是半双工模式效率差。匿名管道是不命名的它主要用于单机版的本地系统中父进程与它启动的子进程之间的通信。命名管道则高级一些通过一个名字进行标识使客户端和服务端应用程序能够通过该管道进行通信。命名管道能够在不同系统的进程间使用这使它成为许多客户/服务器应用程序的理想之选。CreateNamedPipe()ConnectNamedPipe(),CreateEvent(),WriteFile(). 5消息方式 消息是利用Windows的驱动机制进行进程通信就是使用消息激活某种操作的过程。对于进程间的通信有用户自定义的消息和Windows消息适合少量数据的频繁通信根据定义的消息号用SendMessage发送 6信号量 信号量是一个计数器可以用来控制多个进程对共享资源的访问。它常作为一种锁机制防止某进程正在访问共享资源时其他进程也访问该资源Linux下定义了多种信号量使用比较常见 7套接字socket socket是最常见的进程间通信方式尤其是跨网络情况下常见的客户端/服务器模式就是典型的跨网络进程交互通过三次握手四次挥手实现安全的通信
2.通信安全
1加join,使其变为串行 2使用互斥锁确保进程间安全的访问共享资源互斥锁既可用于线程也可用于进程