c++ 多线程学习

原创 2015年11月18日 17:49:57

最近在研究实时处理问题,学习了相关多线程的知识,这里进行简单的学习总结。

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++ 多线程学习总结

先来一个简单的例子,展示如何创建一个线程 #include #include #include using namespace std; unsigned Counter; uns...
  • hust_bochu_xuchao
  • hust_bochu_xuchao
  • 2016年11月08日 11:06
  • 782

windows下C++多线程学习之一(多线程基础)

作为一个C++程序员,相信大家对多线程都不陌生。最近自己在系统的学习多线程编程,发现了很多曾经没有注意到的东西,系统的整理了一下这些知识。方便自己以后查阅,也希望能够能够方便他人。 一、...
  • hcc1991
  • hcc1991
  • 2016年05月07日 17:37
  • 1614

Windows环境下C++多线程TCP通信

最近突然对传输层的东西有了兴趣...发现自己虽然学过计网也学过C++,却没有真正实现过客户端和服务器之间的通信,于是恶补了一下socket知识,再加上大佬们的指导,模仿着写了个demo... 直接上...
  • sinat_23118323
  • sinat_23118323
  • 2017年04月30日 12:16
  • 1791

C++服务器(五):pthread多线程编程

多线程采用pthread库。 考虑到多平台下的实现并不会很容易,还有多线程间的同步等问题,采用一个比较通用的库就好了,这样减少很多工作(其实是我不会使用别的库)创建一个线程函数原型:#include...
  • u014613043
  • u014613043
  • 2016年03月19日 20:24
  • 715

c++实现多线程简单例子

C++本身并没有提供任何多线程机制,但是在windows下,我们可以调用SDK win32 api来编写多线程的程序,下面就此简单的讲一下:   创建线程的函数 HANDLE CreateThr...
  • zzuchengming
  • zzuchengming
  • 2016年10月03日 20:22
  • 1772

C++ 多线程编程总结

在开发C++程序时,一般在吞吐量、并发、实时性上有较高的要求。设计C++程序时,总结起来可以从如下几点提高效率: ● l 并发 ● l 异步 ● l 缓存 下面将我平常工作中遇到一些问题例举...
  • fanyun_01
  • fanyun_01
  • 2016年12月12日 22:17
  • 2593

C++多线程socket系统新编

server-socket #include "stdafx.h" #include "winsock2.h" #include #include #include #include #inc...
  • wyansai
  • wyansai
  • 2016年02月28日 23:16
  • 2206

简单的多线程实例C++

与大家分享这个用C++实现的多线程编程。程序很简单,但是很能说明问题,可是当作一个入门程序。...
  • lizi_stdio
  • lizi_stdio
  • 2016年12月20日 14:21
  • 2639

C/C++ 之 多线程 百度、华为、360 面试面试题汇总(一)

本文来自http://blog.csdn.net/morewindows/article/details/7392749无答案解析 以下提供答案参考: 第一题:线程的基本概念、线程的基本状态及状态之...
  • u010236550
  • u010236550
  • 2013年10月07日 09:47
  • 5748

C++学习笔记--多线程

优缺点对比: 多线程开销小,但难于管理,且不能用于分布式系统; 多进程开销大,操作系统会进行一部分管理,因此用户管理就比较简单,可用于分布式; 通常多线程和多进程结合使用。 参考资料:http...
  • du_qi
  • du_qi
  • 2016年08月26日 22:35
  • 1132
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:c++ 多线程学习
举报原因:
原因补充:

(最多只允许输入30个字)