【无标题】

今天是OpenMP库,并发编程的一天

参考链接

https://zhuanlan.zhihu.com/p/608946001?utm_id=0

一.OpenMp的基本介绍
1. 它是gcc自带的,并发编程的标准库,它利用代码块的并行性来并发执行程序
2. 编译时需要加上 -fopenmp 选项
二.例程
下面这个程序是最基本的用法,os会分配可能多的线程去执行代码块中的语句。
```c++
    #include <iostream>
    #include <omp.h>

    using std::cout;
    using std::endl;


    int main()
    {
        int i = 0;
        #pragma omp parallel 
        {
            cout << "hello OpenMP" << i ++ << endl;
        }

        return 0;
    }
```

在这里插入图片描述

从实验结果可以看出一些。

    cout << "hello OpenMP" << i ++ << endl;

上面的操作会被看成多个操作

  1. cout << “hello OpenMP”;
  2. cout << i; i ++;
  3. cout << endl

因此显示的结果五花八门.

三. 控制线程数量
  1. 使用预处理指令设置线程数量

    #include <iostream>
    #include <omp.h>
    
    using std::cout;
    using std::endl;
    
    
    int main()
    {
        int i = 0;
        #pragma omp parallel num_threads(5) 
        {
            cout << "hello OpenMP" << i ++ << endl;
        }
    
        return 0;
    }
    
  2. 使用api函数修改线程数目

    #include <iostream>
    #include <omp.h>
    
    using std::cout;
    using std::endl;
    
    
    int main()
    {
        int i = 0;
    
        omp_set_num_threads(5);
        #pragma omp parallel 
        {
            cout << "hello OpenMP" << i ++ << endl;
        }
    
        return 0;
    }
    
  3. 使用linux命令,修改环境变量

        export OMP_NUM_THREADS=5 # 编译之前
    
四. for loop
```c++
    #include <iostream>
    #include <omp.h>

    using std::cout;
    using std::endl;


    int main()
    {
        int i = 0;

        #pragma omp parallel for 
        for(int i = 0; i < 10; ++i) {
            printf("hello,openmp!  ThreadNO.%d\n",omp_get_thread_num());    
        }

        return 0;
    }
```

这里用的是parallel for,为下面的for循环分配多个线程异步的去执行。
此外,这里用的是printf,而不是cout,从结果上看,printf只有一个输出流
而cout时有多个数处流,这其实也能理解,cout是ostream重载了<<操作符。
![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Fparallel_for_printf.png&pos_id=img-lDFw1vXy-1702910969313在这里插入图片描述

五. 线程同步
```c++
#include <iostream>
#include <omp.h>

using std::cout;
using std::endl;


int main()
{
    int sum = 0;

    #pragma omp parallel for 
    for(int i = 0; i < 10; ++i) {
        sum += i;
        // printf("hello,openmp!  ThreadNO.%d\n",omp_get_thread_num());    
    }
    std::cout << sum << std::endl; //(0 + 9) * 10 / 2
    return 0;
}
```

实验结果如下:
![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2F%E7%BA%BF%E7%A8%8B%E5%90%8C%E6%AD%A5.png&pos_id=img-I15EFV90-1702910969314在这里插入图片描述

从实验结果看出,少了部分加的次数。
这是为什么呢?与数据库并发操作时出现的读未提交错误一致。

解决方案:使用临界区
```c++
    #include <iostream>
    #include <omp.h>

    using std::cout;
    using std::endl;


    int main()
    {
        int sum = 0;

        #pragma omp parallel for 
        for(int i = 0; i < 10; ++i) {
            #pragma omp critical 
            {
                sum += i;
            }
            // printf("hello,openmp!  ThreadNO.%d\n",omp_get_thread_num());    
        }
        std::cout << sum << std::endl; //(0 + 9) * 10 / 2
        return 0;
    }
```

此时输出正确!
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值