c++ 多线程学习
来源:互联网 发布:单片机如何控制电机 编辑:程序博客网 时间:2024/06/06 07:42
最近在研究实时处理问题,学习了相关多线程的知识,这里进行简单的学习总结。
1.多线程能干啥
很多时候,一想到提高效率问题,我们便会想到多线程,那么多线程一定能提高效率吗?如果能,在什么情况下能够提高效率?
当有多个cpu的情况下,计算机可以同时处理多个事件,多线程的处理效率会快很多。如果一个任务可以细分为多个子任务,每个都需要cpu资源和内存资源。如果是单线程的话,就只能等处理完一个子任务的时候才能接下去处理下一个子任务。而在多线程的情况下,可以在第一个子任务用完cpu资源的时候,假如此时他只需要io资源(举个例子,比如说读写文件),这个时候在等待他处理的时候,可以同时处理第二个任务。
但当只有一个cpu的时候,多线程可能快也可能慢。可能慢的原因是系统在多线程之间的切换占据了一定的时间,反而增加了时耗。可能快的原因是合理利用多线程的特点,同时做不冲突的事,比如一个线程在读写文件,一个线程在处理。
2.多线程简单实现
首先,认识一下多线程创建函数
HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD SIZE_T dwStackSize, // initial stack size LPTHREAD_START_ROUTINE lpStartAddress, // thread function LPVOID lpParameter, // thread argument DWORD dwCreationFlags, // creation option LPDWORD lpThreadId // thread identifier);
结构中的参数介绍:
lpThreadAttributes:指向SECURITY_ATTRIBUTES型态的结构的指针,通常设为NULL;
dwStackSize:设置初始栈的大小,以字节为单位,通常设为0;
lpStartAddress:指向线程函数的指针,形式:@函数名,函数名称没有限制,但是必须以下列形式声明:
DWORD WINAPI 函数名 (LPVOID lpParam) ,格式不正确将无法调用成功。
lpParameter:向线程函数传递的参数,是一个指向结构的指针,不需传递参数时,为NULL。
dwCreationFlags :线程标志。取0时表示创建立即激活线程;
lpThreadId:保存新线程的id,通常设为NULL。
下面实现一个简单的多线程例子。
#include <iostream>#include <Windows.h>using namespace std;DWORD WINAPI DISPLAY1(LPVOID lpParameter){ while(1) { cout<<"1"<<endl; Sleep(1000); }}DWORD WINAPI DISPLAY2(LPVOID lpParameter){ while(1) { cout<<"2"<<endl; Sleep(1000); }}int main(){ HANDLE pThread1=CreateThread(NULL,0,DISPLAY1,NULL,0,NULL); HANDLE pThread2=CreateThread(NULL,0,DISPLAY2,NULL,0,NULL); CloseHandle(pThread1); CloseHandle(pThread2); while(1) { cout<<"0"<<endl; Sleep(1000); } return 0;}
出现如下结果:
可以发现,输出行有时会存在换行和输出的交错,主要的原因是因为多线程并发运行时,多个线程之间如果公用了一些资源的话,我们并不能保证这些资源都能正确地被利用,因为这个时候资源并不是独占的。而这里的endl就是公用资源。如何解决这一问题呢?这里提供两种解决方案。
(1)将cout<<"0"<<endl
换成`cout<<”0\n”;
通过多线程不共用资源的方式,解决了输出紊乱的问题;
(2)利用多线程同步
对于一个资源被多个线程共用会导致程序的混乱,我们的解决方法是只允许一个线程拥有对共享资源的独占,这样也能够解决上面的问题了。`
HANDLE CreateMutex( LPSECURITY_ATTRIBUTES lpMutexAttributes, // SD BOOL bInitialOwner, // initial owner LPCTSTR lpName // object name );
该函数用于创造一个独占资源,第一个参数我们没有使用,可以设为NULL,第二个参数指定该资源初始是否归属创建它的进程,第三个参数指定资源的名称。
HANDLE hMutex = CreateMutex(NULL,TRUE,"screen");
这条语句创造了一个名为screen并且归属于创建它的进程的资源。
BOOL ReleaseMutex( HANDLE hMutex // handle to mutex );
该函数用于释放一个独占资源,进程一旦释放该资源,该资源就不再属于它了,如果还要用到,需要重新申请得到该资源。申请资源的函数如下:
DWORD WaitForSingleObject( HANDLE hHandle, // handle to object DWORD dwMilliseconds // time-out interval );
第一个参数指定所申请的资源的句柄,第二个参数一般指定为INFINITE,表示如果没有申请到资源就一直等待该资源,如果指定为0,表示一旦得不到资源就返回,也可以具体地指定等待多久才返回,单位是千分之一秒。
下面程序是对上面例子的修改:
#include <iostream>#include <Windows.h>HANDLE hMutex;using namespace std;DWORD WINAPI DISPLAY1(LPVOID lpParameter){ while(1) { WaitForSingleObject(hMutex,INFINITE); cout<<"1"<<endl; Sleep(1000); ReleaseMutex(hMutex); }}DWORD WINAPI DISPLAY2(LPVOID lpParameter){ while(1) { WaitForSingleObject(hMutex,INFINITE); cout<<"2"<<endl; Sleep(1000); ReleaseMutex(hMutex); }}int main(){ HANDLE pThread1=CreateThread(NULL,0,DISPLAY1,NULL,0,NULL); HANDLE pThread2=CreateThread(NULL,0,DISPLAY2,NULL,0,NULL); hMutex=CreateMutex(NULL,FALSE,NULL); CloseHandle(pThread1); CloseHandle(pThread2); while(1) { WaitForSingleObject(hMutex,INFINITE); cout<<"0"<<endl; Sleep(1000); ReleaseMutex(hMutex); } return 0;}
- C 多线程学习
- c 多线程,多进程 学习
- Linux 下 c 多线程学习
- [C#] C#多线程学习(一) 多线程的相关概念
- [C#] C#多线程学习(五) 多线程的自动管理(定时器)
- C++:多线程编程学习:利用多线程进行归并排序。
- C#.net多线程的学习 (自学篇)
- c#.net 多线程编程学习(1)
- c#.net 多线程编程学习(2)
- c#.net 多线程编程学习(3)
- Linux C 多线程编程学习(二)
- C++/GUI/Qt学习——多线程
- Linux-(C)多线程学习(入门)
- C 多线程
- C 多线程
- C++:多线程
- c# 多线程
- C#---多线程
- windows 操作系统版本号
- 软件编码原则
- iphone SprintBoard部分私有API总结
- Use your anger!
- 【原创】GBDT(MART)概念简介
- c++ 多线程学习
- MySQL上的一些操作
- Oracle使用split和splitstr函数批量分隔字符串
- 数据库日志文件-- undo log 、redo log、 undo/redo log
- http://www.jeasyui.net
- PopupWindow + RecyclerView的使用
- GNU make 101
- marionette中的View的el id className tagName 属性
- 南大软院大神养成计划——第三天