使用互斥锁的getter和setter最佳实践

问题描述 投票:0回答:1

当在嵌入式编程中使用多个线程时,我感到有点不知所措,因为每个共享资源最终都有一个由互斥锁保护的getter / setter方法。我真的很想了解是否有以下类型的吸气剂

static float static_raw;
float get_raw() {
    os_mutex_get(mutex, OS_WAIT_FOREVER);
    float local_raw = static_raw;
    os_mutex_put(mutex);

    return local_raw ;
}

有意义,或者是否可以将浮动分配视为原子,例如对于ARM(与例如64位变量不同)使其显得多余。我可以理解这样的内容

raw = raw > VALUE ? raw + compensation() : raw;

其中多次处理该值,但在读取/返回值时呢?你能使我头脑清晰吗?

问候,

c embedded race-condition freertos shared-resource
1个回答
0
投票

C标准对赋值运算符的原子性没有任何规定。您不能考虑原子分配,因为它完全取决于实现。

在C11中,_Atomic关键字可用于声明要原子读取和写入的变量,因此您可以例如执行以下操作:

static _Atomic float static_raw;

float get_raw() {
    return static_raw;
}

如果这样做,请不要忘记使用-std=c11进行编译。


这是一个可行的示例(使用gcc -std=c11 -lpthread x.c编译:]]

#include <stdio.h>
#include <pthread.h>

static _Atomic int atomic_counter;
static int counter;

void *f(void* _unused) {
    for(int i = 0; i < 1000; i++) {
        atomic_counter++;
        counter++;
    }

    return NULL;
}

int main(void) {
    pthread_t thr[10];

    for(int i = 0; i < 10; i++)
        pthread_create(&thr[i], NULL, f, NULL);
    for(int i = 0; i < 10; i++)
        pthread_join(thr[i], NULL);

    printf("Atomic: %u, non-atomic: %u\n", atomic_counter, counter);

    return 0;
}

不同运行的输出:

Atomic: 10000, non-atomic: 8413
Atomic: 10000, non-atomic: 9943
Atomic: 10000, non-atomic: 7538
Atomic: 10000, non-atomic: 9752
Atomic: 10000, non-atomic: 9037
Atomic: 10000, non-atomic: 9477
Atomic: 10000, non-atomic: 8762
© www.soinside.com 2019 - 2024. All rights reserved.