多线程,进程,同步互斥
来源:互联网 发布:淘宝上可靠的代购店铺 编辑:程序博客网 时间:2024/06/05 17:30
首先,简单了解三个概念
程序: 静态描述怎么运行的文本,可以说是指令集合
进程: 是具有一定独立功能的程序关于某个数据集合上的一次运行活动。(官方解释)
是系统进行资源分配和调度的一个独立单位.
线程:进程中单一顺序的控制流。也可以说是轻量级进程。目前程序执行的最小单元。
是CPU调度和分派的基本单位.他不拥有自己的资源,但共享进程的资源.
【程序】没有资源不能独立运行起来,所以产生了【进程】。一个程序可以有多个进程。
【进程】同一时间不能完全大量的工作,所以将自己分流程了【线程】。一个进程可以有多个线程。
【线程】划分到很细了,他的优点:提高了进程的并发度,有效利用多处理机和多和计算机。
线程与进程的区别:
①、线程是指进程内的一个执行单元,也是进程内的可调度实体.
②、进程有自己的独立地址空间,进程之间资源不共享。线程因为是一个进程分流下来,所以共享资源。(本质区别)
③、线程是处理器调度的基本单位。
④、进程的并发执行属于处理器上的抽象,线程的并发执行则是比进程更深一层的抽象。
简而言之,
线程的划分尺度小于进程,使得多线程程序的并发性高。
另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。
为什么使用多线程:
这个不多说了.....总之就是忙到你想要三头六臂时,他就出现了.
优点:
1.繁忙的处理或计算一些大数据时,为了保证主线程不一直等待,这种应该交给后台的线程去做.
2.使资源得到最优化分配.
3.缩短完成任务的时间
缺点:
1.操作系统需要切换线程,所以大量使用反而变得更慢
2.线程多了,BUG也多了
3.需要更大的内存空间
4.保证程序的安全性(死锁,中止).
使用线程:
C/C++
include<thread>; //线程的类都在这里 void threadFunc(){ //线程内容 std::cout<<"hello world";}int main(){ std::thread t1=(threadFunc); //启动线程 t1.join(); //保证t1执行完毕才主线程才能关闭. return 0;}也可以使用λ方式写,总之线程的开源代码: http://www.oschina.net/question/12_45346
JAVA
第一种方法: 继承thread类
class MyThread extends Thread{ public void run() { //线程内容 }}public static void main( String[ ] args ){ ( new MyThread( ) ).start(); //启动线程}
第二种方法: 用Runnable接口 (一般用这种,因为继承只能继承一种,但能对很多种接口
class MyThread implents Runnable{ public void run() { //线程内容 }}public static void main( String[ ] args ){ ( new thread( new MyThread( ) ) ).start(); //启动线程}
android
通常创建线程是使用JAVA的上面两种的结合版.
不用继承thread,也不用实现runnable接口直接实例化一个thread,实现runnable的匿名内部类
Thread mThread = new Thread(new Runnable() { @Override public void run() { try { while (true) { //线程内容 } } catch (InterruptedException e) { e.printStackTrace(); } } }); mThread.start();
安卓的多线程还需要涉及的技术有:handler,Message,MessageQueue,Looper,HandlerThread
在主线程定义handler来对消息进行反应,有Message 和 Post 两种写法
Message写法是要重载handleMessage函数
//Looper.preper(); 初始化Looper private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case 0://内容 } } };//Looper.loop(); 启动消息队列头尾两句只有在子线程中才需要,UI线程中已有消息队列不用绑定了.
在子线程中发送消息
Message message = new Message();message.obj = timer;message.what = 0;handler.sendMessage(message);
POST写法,直接在子线程发送一个runnable,然后主线程中执行
handler.post(new Runnable() { @Override public void run() { tvMessage.setText("使用Handler.post在工作线程中发送一段执行到消息队列中,在主线程中执行。"); }});
同步与互斥
用户模式:原子操作,临界区
内核模式:事件,信号量,互斥量
原子操作
不可分割的一个指令,一执行就做到结束为止,不可中断.
临界区
EnterCriticalSection() 进入临界区
LeaveCriticalSection() 离开临界区
两个对应着出现.保证单个线程访问数据,其他试图进入的线程将被挂起,直到之前的离开临界区.
实现同进程的线程同步
事件
使用通知的方式,实现不同进程的线程同步
CreateEvent() 创建一个信号量 OpenEvent() 打开一个事件 SetEvent() 回置事件 WaitForSingleObject() 等待一个事件 WaitForMultipleObjects() 等待多个事件WaitForMultipleObjects 函数原型: WaitForMultipleObjects( IN DWORD nCount, // 等待句柄数 IN CONST HANDLE *lpHandles, //指向句柄数组 IN BOOL bWaitAll, //是否完全等待标志 IN DWORD dwMilliseconds //等待时间 )
互斥量
每两个线程成互斥,互斥对象只有一个,所以保证数据访问的安全.而且能跨进程实现.
CreateMutex() 创建一个互斥量 OpenMutex() 打开一个互斥量 ReleaseMutex() 释放互斥量 WaitForMultipleObjects() 等待互斥量对象
信号量
PV操作..,S可以设置初始值,即允许最大有多少个线程访问.
P申请空间:S-1
V释放空间S+1
CreateSemaphore() 创建一个信号量 OpenSemaphore() 打开一个信号量 ReleaseSemaphore() 释放信号量 WaitForSingleObject() 等待信号量
#include "stdafx.h"#include "windows.h"#include "stdio.h"volatile int ThreadData = 1;CRITICAL_SECTION csPrint; // 临界区//HANDLE evtPrint; // 事件信号,标记事件是否已发生//HANDLE mtxPrint; // 互斥信号,如有信号表明已经有线程进入临界区并拥有此信号//HANDLE smphPrint; // 信号量,表示是否已经达到允许的最大线程数void Print(char *str){ EnterCriticalSection(&csPrint); // 进入临界区 //WaitForSingleObject(evtPrint, INFINITE); // 等待事件有信号 //WaitForSingleObject(mtxPrint, INFINITE); // 等待互斥量空置(没有线程拥有它) //WaitForSingleObject(smphPrint, INFINITE); // 等待对共享资源请求被通过 等于 P操作 for (;*str != '\0';str++) { Sleep(50); printf("%c",*str); } printf("\n"); LeaveCriticalSection(&csPrint); // 退出临界区 //SetEvent(evtPrint); // 把事件信号量恢复,变为有信号 //ReleaseMutex(mtxPrint); // 释放对互斥量的占有 //ReleaseSemaphore(smphPrint, 1, NULL); // 释放共享资源 等于 V操作 }void ThreadProcess(){ for(int i=0; i<6; i++) { Sleep(1000); Print("Sub Thread is running!"); } ThreadData = 0;}int _tmain(int argc, _TCHAR* argv[]){ HANDLE hThread; DWORD ThreadID; InitializeCriticalSection(&csPrint); // 初始化临界区 //evtPrint = CreateEvent(NULL, FALSE, TRUE, L"PrintEvent"); // 初始化事件 //mtxPrint = CreateMutex(NULL, FALSE, L"PrintMutex"); // 初始化互斥量 //smphPrint= CreateSemaphore(NULL, 1, 1, L"PrintSemaphore"); // 设置信号量1个资源,因此同时只可以有一个线程访问 hThread=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProcess, NULL, 0, &ThreadID); while (ThreadData) { Print("Main Thread is waiting for Sub Thread!"); Sleep(600); } printf("Main Thread Finished!"); system("pause"); return 0;}
- 多线程,进程,同步互斥
- 同步与互斥(多线程/多进程)
- 进程同步 & 互斥
- 多线程互斥同步
- 多线程互斥同步
- 多线程同步互斥
- linux多进程多线程互斥同步例子
- linux多进程多线程互斥同步例子
- linux多进程多线程互斥同步例子
- Linux多进程多线程互斥同步例子
- 进程同步与互斥
- 进程同步与互斥
- windows进程同步互斥
- 进程-线程-同步-互斥
- 进程同步互斥,通信
- 进程同步与互斥
- windows进程同步互斥
- 进程同步与互斥
- 华为面试
- win7右键中添加“获取管理员权限”
- WPF DataGrid 选中行颜色不改变问题
- mysql cluster常用命令
- 动规问题概述(待整理)
- 多线程,进程,同步互斥
- 《信息检索》第三周课件、推荐书籍 及 作业
- RockMongo登录mongodb失败的处理办法
- 配置Activiti Explorer
- cache源码分析一 存储机制分析
- 二维计算几何基础
- 第二章 应用服务器调优
- hdu 4405 Aeroplane chess 概率dp
- BEA WebLogic平台下J2EE调优攻略----第三章 数据库调优