gpt4 book ai didi

c++ - omp 单模拟通过 c++11

转载 作者:行者123 更新时间:2023-11-28 06:52:51 25 4
gpt4 key购买 nike

我有多个 std::threads 但其中只有一个 应该执行某些任务(比如 printf)(类似于 pragma omp single )。

我试过修改semaphore code ,但它没有像我预期的那样工作。

#ifndef SEMAPHORE_H
#define SEMAPHORE_H

#include <mutex>
#include <condition_variable>
using namespace std;

class semaphore {
private:
mutex mtx;
condition_variable cv;
int count, countMax;

public:
semaphore(int count_ = 0):count(count_), countMax(count_){;}
void notify()
{
unique_lock<mutex> lck(mtx);
++count;
cv.notify_one();
}
void notifyAll()
{
unique_lock<mutex> lck(mtx);
count = countMax;
cv.notify_all();
}

bool wait()
{
unique_lock<mutex> lck(mtx);
if (--count == 0) {
return true;
} else {
cv.wait(lck, [this]() { return count > 0; });
return false;
}
}
};

#endif // SEMAPHORE_H

和主程序:

#include <iostream>
#include <vector>
#include <thread>
#include "semaphore.h"

semaphore sem(2);
int sum = 0;
std::mutex sumMutex;
int sumPrintAndReturn(int i)
{
{
std::lock_guard<std::mutex> lock(sumMutex);
sum += i;
}
if (sem.wait()) {
std::cout << "Sum (ONCE): " << sum << std::endl;
sem.notifyAll();
}
std::cout << "Sum (EVERY): " << sum << std::endl;
return sum;
}

int main()
{
std::vector<std::thread> threads;
for (int i = 0; i < 2; i++) {
threads.push_back(std::thread(sumPrintAndReturn, i));
}
for (auto& thread: threads)
thread.join();
return 0;
}

问题是最后的总和不同。

Sum (EVERY): 0
Sum (ONCE): 1
Sum (EVERY): 1

那么为什么我要谈论 omp single?这是我期望的示例和输出。

#include <iostream>
#include <omp.h>

int main()
{
int sum = 0;
int global_i = 0;
#pragma omp parallel num_threads(2)
{
int i;
#pragma omp critical
i = global_i++;
#pragma omp atomic
sum += i;
#pragma omp single
printf("Sum (ONCE): %d\n", sum);
printf("Sum (EVERY): %d\n", sum);
}
}

并输出:

Sum (ONCE): 1
Sum (EVERY): 1
Sum (EVERY): 1

我无法回答我的主题,所以我将在此处发布最终和工作变体

#ifndef SEMAPHORE_H
#define SEMAPHORE_H

#include <mutex>
#include <condition_variable>
#include <atomic>
#include <functional>

class semaphore {
private:
std::mutex mtx;
std::condition_variable cv;
std::atomic<int> count;
const int countMax;
bool flag;

void releaseAll()
{
std::unique_lock<std::mutex> lck(mtx);
flag = true;
cv.notify_all();
cv.wait(lck, [this]() { return !flag; });
}

bool wait()
{
std::unique_lock<std::mutex> lck(mtx);
if (--count == 0) {
count++;
return false;
}
else {
cv.wait(lck, [this]() { return flag; });
count++;
if (count == countMax) {
flag = false;
cv.notify_all();
}
cv.wait(lck, [this]() { return !flag; });
return true;
}
}

public:
semaphore(int count_ = 0) :count(count_), countMax(count_), flag(false){ }
void runOnce(std::function<void()> func) {
if (!wait()) {
func();
releaseAll();
}
}


};

#endif // SEMAPHORE_H

最佳答案

问题出在您的 wait 的执行中功能。问题是您处理条件变量的方式... [this]() { return count > 0; }将始终返回 true当您的信号量初始计数为 2 并且您运行两个线程时!

我在下面做了一个小改动,我在其中添加了一个新的 bool 变量来保存“成功”状态,该状态在最终“获胜”线程调用 sem.wait() 时设置。 .我不保证此代码的安全性或功能;它只对我有用 ;)(VS2013 express )。

class semaphore {
private:
mutex mtx;
condition_variable cv;
int count, countMax;
bool flag;

public:
semaphore(int count_ = 0) :count(count_), countMax(count_), flag(false){ ; }
void notify()
{
unique_lock<mutex> lck(mtx);
++count;
cv.notify_one();
}
void notifyAll()
{
unique_lock<mutex> lck(mtx);
count = countMax;
cv.notify_all();
}

bool wait()
{
unique_lock<mutex> lck(mtx);
if (--count == 0) {
flag = true;
return true;
}
else {
cv.wait(lck, [this]() { return flag; });
return false;
}
}
};

示例输出: 总和(一次):1 总和(每个):1 总和(每个):1

注意:由于我回答了这个问题,问题中的原始代码已更改。为了完整起见,我的原始答案保留在下面。


这个函数看起来很可疑:

bool wait()
{
unique_lock<mutex> lck(mtx);
if (--count == 0) {
return true;
} else {
cv.wait(lck, [this]() { return count > 0; });
}
}

只有一个返回值!密切注意您的编译器警告会发现这一点。

$ g++ --std=c++11 -Wall semaphore.cpp
semaphore.cpp: In function ‘int sumPrintAndReturn(int)’:
semaphore.cpp:19:1: warning: no return statement in function returning non-void [-Wreturn-type]
In file included from semaphore.cpp:4:0:
semaphore.h: In member function ‘bool semaphore::wait()’:
semaphore.h:37:5: warning: control reaches end of non-void function [-Wreturn-type]

关于c++ - omp 单模拟通过 c++11,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23594591/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com