导图社区 多线程导图笔记
在一个程序中,这些独立运行的程序片断叫作线程,利用它编程的概念就叫作多线程处理。本图整理了C语言中通过Windows API 操作多线程的一些函数,以及CSharp语言中关于多线程、并行编程、异步编程的类。
编辑于2021-09-05 09:47:29介绍归纳 C Sharp 语音的基础重点知识。包括语言基础、字面常量、程序集、不安全代码、基础类、枚举、数组、泛型、字符串、正则表达式、委托与事件、文件、异常、多线程、异步、反射、网络、绘图、WinForm、Windows、跨平台调用等内容。思维导图示例中,有示例代码,方便学习与练习。
这份思维导图归纳了一些HTML基本的元素标签、布局、表单,以及 HTML5 API 如 WebSockets、Fetch API 等内容。CSS 主要是归纳了选择器。JavaScript 主要是包含了函数与箭头函数、this 关键字、Promise 异步对象。此外还有AJAX、jQuery 与 jQuery AJAX、JSONP 等内容。导图中的注释有很多相关的详细说明与示例代码,其中后端的测试代码是用的 PHP。希望能帮到大家!
WPF开发相关的笔记。WPF基本概念、XAML基本语法、控件与布局、Binding、依赖属性与附加属性、路由事件与附加事件、命令、资源、模板与样式、2D绘图与动画、3D绘图等内容。导图中的注释还有很多相关的详细说明与示例代码,希望能帮到大家!
社区模板帮助中心,点此进入>>
介绍归纳 C Sharp 语音的基础重点知识。包括语言基础、字面常量、程序集、不安全代码、基础类、枚举、数组、泛型、字符串、正则表达式、委托与事件、文件、异常、多线程、异步、反射、网络、绘图、WinForm、Windows、跨平台调用等内容。思维导图示例中,有示例代码,方便学习与练习。
这份思维导图归纳了一些HTML基本的元素标签、布局、表单,以及 HTML5 API 如 WebSockets、Fetch API 等内容。CSS 主要是归纳了选择器。JavaScript 主要是包含了函数与箭头函数、this 关键字、Promise 异步对象。此外还有AJAX、jQuery 与 jQuery AJAX、JSONP 等内容。导图中的注释有很多相关的详细说明与示例代码,其中后端的测试代码是用的 PHP。希望能帮到大家!
WPF开发相关的笔记。WPF基本概念、XAML基本语法、控件与布局、Binding、依赖属性与附加属性、路由事件与附加事件、命令、资源、模板与样式、2D绘图与动画、3D绘图等内容。导图中的注释还有很多相关的详细说明与示例代码,希望能帮到大家!
多任务
概念
并发(Concurrency)
各任务宏观上(时间段上)同时进行,微观上(时刻上)交替进行
并行(Parallelism)
各任务宏观上(时间段上)同时进行,微观上(时刻上)也是同时进行
同步(Synchronous)
调用者需要等到被调用者返回后,才继续往下执行
异步(Asynchronous)
调用者不需要等到被调用者返回,就可以继续往下执行
多线程、多进程
C语言
Windows
Windows对象
Windows创建的Object会被赋予一个状态量
Object被激活或正在使用时,无信号
Object未被使用时,有信号
等待对象信号
WaitForSingleObject(~)
WaitForMultipleObject(~)
多线程
创建
windows.h
CreateThread(~)
线程函数类型:DWORD WINAPI ThreadProc(LPVOID pParm);
process.h(推荐)
_beginthread(~)
线程函数类型:void __cdecl ThreadProc(void* pParm);
结束
windows.h
ExitThread(~) //不推荐调用,最好通过线程函数返回结束
process.h(推荐)
_endthread() //可以在线程函数内调用,也可以通过线程函数返回结束
获取当前线程ID
GetCurrentThreadId()
休眠
Sleep(~)
同步
概念
在互斥的基础上,通过一些机制实现对资源的有序访问
临界区
对象类型
CRITICAL_SECTION
创建
InitializeCriticalSection(~)
删除
DeleteCriticalSection(~)
进入
EnterCriticalSection(~)
提示:不要在临界区调用Sleep或任何Wait函数
离开
LeaveCriticalSection(~)
事件
创建
CreateEvent(~)
触发事件(使有信号)
SetEvent(~)
解除事件触发(使无信号)
ResetEvent(~)
自动模式下不需要调用
等待事件
使用 WaitForSingleObject(~)
线程本地存储
WinAPI实现
线程外
分配TLS并获取索引
例:DWORD tlsId = TlsAlloc();
释放指定TLS
例:TlsFree(tlsId);
线程内
为索引分配数据内存
例:TlsSetValue(tlsId, GlobalAlloc(GPTR, sizeof(int)));
根据索引获取数据内存
例:int* ptd = TlsGetValue(tlsId);
释放数据内存
例:GlobalFree(ptd);
MSVC C语言扩展
变量声明前加 __declspec(thread)
例:__declspec(thread) TDATA td;__declspec(thread) static TDATA td; //局部要加 static
多进程
创建
CreateProcess(~)
同步
互斥对象
创建
CreateMutex(~)
关闭
CloseHandle(~)
加锁
WaitForSingleObject(~)
解锁
ReleaseMutex(~)
信号量
创建
CreateSemaphore(~)
关闭
CloseHandle(~)
申请
WaitForSingleObject(~)
释放
ReleaseSemaphore(~)
C++
多线程
C++11
C#
多线程
创建
命名空间:System.Threading
类:Thread
例:Thread thr = new Thread(new ThreadStart(obj.Fun));thr.Start(~);
获取当前线程ID
Thread.CurrentThread.ManagedThreadId
休眠
Thread.Sleep(~)
同步
lock语句与Monitor类
lock语句
作用
将语句块标记为临界区
格式
lock (对象或表达式) {......}
最好锁定 private 对象
等价于:bool lockTaken false;try{ System.Threading.Monitor.Enter(对象或表达式, ref lockTaken); if (lockTaken) { ...... }}finally{ if (lockTaken) System.Threading.Monitor.Exit(对象或表达式);}
例:class Num{ private Object thisLock = new Object(); //或 private static readonly Object thisLock = new Object(); public void Test() { lock (thisLock) { ...... } }}
ReaderWriterLock类
定义支持单个写线程和多个读线程的锁
Interlocked类
为多个线程共享的变量提供原子操作
thr.Join(~) 方法
等到线程终止后返回
事件
AutoResetEvent类
自动重置事件
主要方法
Set()
触发事件
Reset()
解除触发事件
WaitOne(~)
等待事件
ManualResetEvent类
手动重置事件
Mutex类
互斥对象,一般用于进程间同步
Semaphore类
信号量,一般用于在进程间限制可同时访问某一资源的进(线)程数
WaitHandle类
等待句柄,是一个抽象类。是事件、互斥对象、信号量等的基类
线程池
ThreadPool类
使用ThreadPool.QueueUserWorkItem(~)提交任务,系统根据任务自动创建线程执行
线程计时器
Timer类
在单独线程中定期执行任务
提示:Timer对象使用完毕后,应调用Dispose()方法释放资源
集合的线程安全性
非泛型集合
IsSynchoronized属性指示是否线程安全
SyncRoot属性获取可同步对集合的访问的对象
供lock语句等使用
Synchronized(~)静态方法获取一个线程安全的包装对象
泛型集合
命名空间System.Collections.Concurrent中提供了线程安全的“并发集合类”
窗体中的线程
其他线程中操作界面
需要将这个操作的任务交给创建界面的线程处理
通过界面对象(窗体或控件)的“同步”Invoke(~)或“异步”BeginInvoke(~)方法完成任务提交
可以通过控件的InvokeRequired属性判断是否需要提交
BackgroundWorker类
调用其RunWorkerAsync(~)方法,激发DoWork事件执行任务(该事件相对于界面线程是异步的)。方法的参数还会传给事件EventArgs参数的Argument成员。
调用其ReportProgress(~)方法,激发ProgressChanged事件报告任务进度任务。方法的参数还会传给事件EventArgs参数的ProgressPercentage成员。
任务完成后,会激发RunWorkerCompleted事件表示任务完成。任务正常完成时,DoWork事件EventArgs参数的Result成员还会传给RunWorkerCompleted事件EventArgs参数的Result成员。任务被取消时,RunWorkerCompleted事件EventArgs参数的Cancelled成员值为true。任务出现异常时,RunWorkerCompleted事件EventArgs参数的Error成员值不为null。
调用其CancelAsync()方法,取消任务执行。
并行编程
概念
并行程序一般将一个任务分解为多个相互独立的子任务,每个子任务分别由不同的处理器执行,最后,综合各子任务的结果形成整个任务的结果。
C#从.Net Framework 4(最好使用4.5以上)起引入了新的类库Task Parallel Libary (任务并行库),是命名空间System.Threading和System.Threading.Tasks中的一组公共类型API。
Task类
创建、执行任务
例:Task<TResult> task = new TaskFactory().StartNew(~);或Task<TResult> task = Task.Run(~);
返回值类型
Task
表示一个异步操作
Task<TResult>
表示一个可以返回值的异步操作
其中,泛型参数类型是具体任务方法的返回值类型
要得到任务结果,可以使用其Result属性,该属性的get访问器会阻塞调用线程直到任务返回。例:TResult result = task.Result;
等待任务完成
task.Wait(~);
等待所有任务完成
Task.WaitAll(~)
为当前task指定一个完成后的延续任务
task.ContinueWith(~)
多个task的异常合并处理
例:try{ Task.Wait(~);}catch (AggregateException ex){ foreach (Exception inner in ex.InnerExceptions) { ...... }}
Parallel类
任务并行
Parallel.Invoke(~)
数据并行
针对范围
Parallel.For(~)
针对集合
Parallel.ForEach(~)
停止执行
上面2个循环委托参数中声明一个ParallelLoopState类型的参数,再在其方法体内调用该参数的Stop()方法
并行Linq (PLinq)
命名空间 System.Linq
对任一Enumerable对象使用AsParallel()方法即可得到并行的查询
例:int[] sor = new int[10];var q = sor.AsParallel().Where(n => n>5);
异步编程
概念
将一些耗时的操作用别的线程执行,必要时等待其结果
async和await
是C#5.0引入的关键字
async是一个修饰符,表明一个方法是异步方法
await是一个操作符,表示等待异步方法执行完毕,并取得Result,实现同步操作
内部有await的方法,必须声明为async方法
例:Task<double> CalcuAsync(int n){ return Task.Run(() => { //由Task线程执行 double s = 1; //计算操作 return s; });} async void CalcuNumberAsync() //异步方法的返回值类型必须为void、Task、Task<T>、或类似Task的类型{ Task<double> calcuNumberTask = CalcuAsync(123); //其他不依赖异步任务返回值的操作 //由调用方线程执行,之后控制权直接交给上层调用者 double result = await calcuNumberTask; //await之后的操作将由Task线程完成执行}
异步方法与事件
如 System.Net.WebClient 类中的 DownloadStringAsync 方法与 DownloadStringCompleted 事件
委托异步调用
委托的BeginInvoke方法进行异步调用
委托的EndInvoke方法等待异步调用完成
例:double Calcu(int n){ double s = 1; //计算操作 return s;} void CalcuNumber(){ Func<int, double> dFunc = Calcu; IAsyncResult calcuRes = dFunc.BeginInvoke(123, null, null); //该方法第3个参数会传给第2个参数即回调方法中参数的AsyncState属性 //其他不依赖异步调用方法返回值的操作 double result = dFunc.EndInvoke(calcuRes); //等待异步调用完成并取得结果}