C++_多线程

一、基本概念

说到多线程编程,那么就不得不提并行并发,多线程是实现并发(并行)的一种手段。并行是指两个或多个独立的操作同时进行。注意这里是同时进行,区别于并发,在一个时间段内执行多个操作。在单核时代,多个线程是并发的,在一个时间段内轮流执行;在多核时代,多个线程可以实现真正的并行,在多核上真正独立的并行执行。例如现在常见的4核4线程可以并行4个线程;4核8线程则使用了超线程技术,把一个物理核模拟为2个逻辑核心,可以并行8个线程。

一般情况下,两种类型的多任务处理:基于进程和基于线程

  • 基于进程的多任务处理是程序的并发执行。
  • 基于线程的多任务处理是同一程序的片段的并发执行。

多进程并发

使用多进程并发是将一个应用程序划分为多个独立的进程(每个进程只有一个线程),这些独立的进程间可以互相通信,共同完成任务。由于操作系统对进程提供了大量的保护机制,以避免一个进程修改了另一个进程的数据,使用多进程比多线程更容易写出安全的代码。但这也造就了多进程并发的两个缺点:

  • 在进程件的通信,无论是使用信号、套接字,还是文件、管道等方式,其使用要么比较复杂,要么就是速度较慢或者两者兼而有之。
  • 运行多个线程的开销很大,操作系统要分配很多的资源来对这些进程进行管理。

由于多个进程并发完成同一个任务时,不可避免的是:操作同一个数据和进程间的相互通信,上述的两个缺点也就决定了多进程的并发不是一个好的选择。

多线程并发

多线程并发指的是在同一个进程中执行多个线程。有操作系统相关知识的应该知道,线程是轻量级的进程,每个线程可以独立的运行不同的指令序列,但是线程不独立的拥有资源,依赖于创建它的进程而存在。也就是说,同一进程中的多个线程共享相同的地址空间,可以访问进程中的大部分数据,指针和引用可以在线程间进行传递。这样,同一进程内的多个线程能够很方便的进行数据共享以及通信,也就比进程更适用于并发操作。由于缺少操作系统提供的保护机制,在多线程共享数据及通信时,就需要程序员做更多的工作以保证对共享数据段的操作是以预想的操作顺序进行的,并且要极力的避免死锁(deadlock)

二、一个简单例子

#include 
#include 
using namespace std;
void output(int i)
{
    cout << i << endl;
}
int main()
{
    
    for (uint8_t i = 0; i < 4; i++)
    {
        thread t(output, i);
        t.detach(); 
    }
    return 0;
}

控制台却只有一个,同时只能有一个线程拥有这个唯一的控制台。

三、一些说明

1.一定要在和线程相关联的thread销毁前,确定以何种方式等待线程执行结束。C++11有两种方式来等待线程结束

  • detach方式,启动的线程自主在后台运行,当前的代码继续往下执行,不等待新线程结束。前面代码所使用的就是这种方式。
  • join方式,等待启动的线程完成,才会继续往下执行。假如前面的代码使用这种方式,其输出就会0,1,2,3,因为每次都是前一个线程输出完成了才会进行下一个循环,启动下一个新线程。

2.默认的会将传递的参数以拷贝的方式复制到线程空间,即使参数的类型是引用。调用std::ref。

#include 
#include 
using namespace std;

class _tagNode
{
public:
    int a;
    int b;
};

void func(_tagNode &node)
{
    node.a = 10;
    node.b = 20;
}

int main()
{
    _tagNode node;

    thread t(func, ref(node));//否则会出现问题
    t.join();

    cout << node.a << endl ;
    cout << node.b << endl ;
}

四、加锁的三种方式

1.

std::mutex mu;
mu.lock();
// 互斥访问部分
mu.unlock();

2.

std::lock_guard guard(mu); // lock_guard 可自动解锁, 避免异常导致无法解锁
std::cout << msg << id << std::endl;

3.

/方便加解锁,但性能不如lock_guard
std::unique_lock locker(m_mutex,std::defer_lock);
//....
locker.lock();
f << "From" << id << ": " << value << std::endl;
locker.unlock();

根据网上教程在github放上了代码:https://github.com/gentlemanman/threads_tutorial_c-11

参考:

http://www.runoob.com/cplusplus/cpp-multithreading.html

https://www.cnblogs.com/wangguchangqing/p/6134635.html

 

 

 

 

你可能感兴趣的:(C++)