Table of Contents:

对于C++而言,当我们需要使用多线程时,可以使用boost::thread库或者自从C++ 11开始支持的std::thread
也可以使用操作系统相关的线程API,如在Linux上,可以使用pthread库。
除此之外,还可以使用omp来使用多线程。它的好处是跨平台,使用简单。
在Linux平台上,如果需要使用omp,只需在编译时使用"-fopenmp"指令。
在Windows的visual studio开发环境中,开启omp支持的步骤为“项目属性 -> C/C++ -> 所有选项 -> openmp支持 -> 是(/openmp)”。

openmp入门简介

openmp是由一系列#paragma指令组成,这些指令控制如何多线程的执行程序。另外,即使编译器不支持omp,程序也也能够正常运行,只是程序不会多线程并行运行。以下为使用omp的简单的例子:

int main()
{
    vector<int> vecInt(100);
        #pragma omp parallel for
    for (int i = 0; i < vecInt.size(); ++i)
    {
        vecInt[i] = i*i;
    }
    return 0;
}

以上代码会自动以多线程的方式运行for循环中的内容。如果你删除#pragma omp parallel for这行,程序依然能够正常运行,唯一的区别在于程序是在单线程中执行。由于C和C++的标准规定,当编译器遇到无法识别的#pragma指令时,编译器自动忽略这条指令。所以即使编译器不支持omp,也不会影响程序的编译和运行。

OpenMP执行模式

OpenMP采用fork-join的执行模式。开始的时候只存在一个主线程,当需要进行并行计算的时候,派生出若干个分支线程来执行并行任务。当并行代码执行完成之后,分支线程会合,并把控制流程交给单独的主线程。

通俗地来讲呢,就是一个老大把收下的小弟分配出去做不同的事情,然后设置集合地点,叫小弟干完事情到指定的地点集合,然后再把小弟分配出去。然后对小弟干事情方式还得进行管控,比如某些事得小弟排着队干;某些事一个小弟干就够了,其它小弟得在旁边休息等这个小弟干完;某些事一个小弟干,其它小弟可以各干个的;某些事只能大哥干,其它小弟忙活别的去……等等。成对的fork和join之间的区域称之为并行域,fork创建新线程,join就是多个线程的汇合。在这个模型中,一开始只有一个主线程——老大,然后主线程遇到相关的命令就会创建多个线程——小弟。

OpenMP就是一个关于如何控制并行域,并行域中的任务是如何分配给每个线程,该如何设置集合点控制各个线程,各个线程之间该如何访问数据、修改数据的一种机制。

OpenMP缺点:

1:作为高层抽象,OpenMp并不适合需要复杂的线程间同步和互斥的场合;
2:另一个缺点是不能在非共享内存系统(如计算机集群)上使用。在这样的系统上,MPI使用较多。