linux 共享内存 整数,使用gcc以原子方式递增Linux x86-64上多个进程的共享内存中的整数...

使用int或std::atomic工程。

关于std::atomic接口的std::atomic是,它与int “ interface”可以很好地协作。 因此,代码几乎完全相同。 您可以通过添加#define USE_INT_IN_SHARED_MEMORY_FOR_SIGNALING_COUNTER true在下面的每个实现之间切换。

我不确定在共享内存中静态创建std::atomic ,因此我使用new布局来分配它。 我的猜测是,依靠静态分配会起作用,但从技术上讲,这可能是未定义的行为。 弄清楚这超出了我的问题范围,但是对此主题发表评论将是非常受欢迎的。

signalling_incrementing_counter.h#include

#include "gpu_base_constants.h"

struct SignalingIncrementingCounter {

public:

/**

* We will either count up or count down to the given limit. Once the limit is reached, whatever is waiting on this counter will be signaled and allowed to proceed.

*/

void init(const int upper_limit_);

void reset_to_empty();

void increment(); // only valid when counting up

void block_until_full(const char * comment = {""});

// We don't have a use-case for the block_until_non_full

private:

int upper_limit;

#if USE_INT_IN_SHARED_MEMORY_FOR_SIGNALING_COUNTER

volatile int value;

#else // USE_INT_IN_SHARED_MEMORY_FOR_SIGNALING_COUNTER

std::atomic value;

std::atomic * value_ptr;

#endif // USE_INT_IN_SHARED_MEMORY_FOR_SIGNALING_COUNTER

pthread_mutex_t mutex;

pthread_cond_t cv;

};

signalling_incrementing_counter.cpp#include

#include

#include "signaling_incrementing_counter.h"

void SignalingIncrementingCounter::init(const int upper_limit_) {

upper_limit = upper_limit_;

#if !GPU_USE_INT_IN_SHARED_MEMORY_FOR_SIGNALING_COUNTER

value_ptr = new(&value) std::atomic(0);

#endif // GPU_USE_INT_IN_SHARED_MEMORY_FOR_SIGNALING_COUNTER

{

pthread_mutexattr_t attr;

pthread_mutexattr_init(&attr);

int retval = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);

if (retval) {

throw std::runtime_error("Error while setting sharedp field for mutex");

}

pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);

pthread_mutex_init(&mutex, &attr);

pthread_mutexattr_destroy(&attr);

}

{

pthread_condattr_t attr;

pthread_condattr_init(&attr);

pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);

pthread_cond_init(&cv, &attr);

pthread_condattr_destroy(&attr);

}

reset_to_empty(); // should be done at end, since mutex functions are called

}

void SignalingIncrementingCounter::reset_to_empty() {

int mutex_rv = pthread_mutex_lock(&mutex);

if (mutex_rv) {

throw std::runtime_error("Unexpected error encountered while grabbing lock. Investigate.");

}

value = 0;

// No need to signal, because there is no function that unblocks when the value changes to 0

pthread_mutex_unlock(&mutex);

}

void SignalingIncrementingCounter::increment() {

fprintf(stderr, "incrementing\n");

int mutex_rv = pthread_mutex_lock(&mutex);

if (mutex_rv) {

throw std::runtime_error("Unexpected error encountered while grabbing lock. Investigate.");

}

++value;

fprintf(stderr, "incremented\n");

if (value >= upper_limit) {

pthread_cond_broadcast(&cv);

}

pthread_mutex_unlock(&mutex);

}

void SignalingIncrementingCounter::block_until_full(const char * comment) {

struct timespec max_wait = {0, 0};

int mutex_rv = pthread_mutex_lock(&mutex);

if (mutex_rv) {

throw std::runtime_error("Unexpected error encountered while grabbing lock. Investigate.");

}

while (value < upper_limit) {

int val = value;

printf("blocking during increment until full, value is %i, for %s\n", val, comment);

/*const int gettime_rv =*/ clock_gettime(CLOCK_REALTIME, &max_wait);

max_wait.tv_sec += 5;

const int timed_wait_rv = pthread_cond_timedwait(&cv, &mutex, &max_wait);

if (timed_wait_rv)

{

switch(timed_wait_rv) {

case ETIMEDOUT:

break;

default:

pthread_mutex_unlock(&mutex);

throw std::runtime_error("Unexpected error encountered. Investigate.");

}

}

}

pthread_mutex_unlock(&mutex);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值