gpt4 book ai didi

C 读取器和写入器线程

转载 作者:行者123 更新时间:2023-11-30 15:34:02 25 4
gpt4 key购买 nike

我正在编写具有以下结构的 C 多线程程序:

struct mystruct {
int a;
int b;
int c;
int d;
} Data;


void *thr_1();
void *thr_2();


int main(int argc, char *argv[]) {
pthread_t t_1,
t_2;

if (pthread_create(&t_1, NULL, thr_1, NULL)
|| pthread_create(&t_2, NULL, thr_2, NULL)) {
perror("pthread_create() on main()");
return -1;
}

while (a < 2000) {
/* do a lot of stuff with Data (never writes on it) */
}

pthread_cancel(thr_1);
pthread_cancel(thr_2);
pthread_join(thr_1, NULL);
pthread_join(thr_2, NULL);

return 0;
}

/* Threads */
void *thr_1() {
while (1) {
/* Read from stream and write to Data */
usleep(50000);
}
return NULL;
}

void *thr_2() {
while (1) {
/* do some stuff with Data (never writes on it) */
usleep(50000);
}
return NULL;
}

这段代码可以工作,但是经过一些研究(竞争条件和线程安全),很明显,由于这些竞争条件,这段代码可能随时失败。当时我的第一个想法是使用互斥锁在写入时锁定结构的成员并在写入后释放它,但是主循环和 thr_2 中对数据结构的读取访问太多。到目前为止,我的解决方案是创建 2 个访问函数,一个用于读取数据,一个用于写入数据,并在这些函数内使用互斥锁来锁定写入。这个丑陋的解决方案对我来说更像是一个黑客......所以,最后,我的问题是:有没有更好的方法来做到这一点?最好没有任何访问数据所需的功能。

非常感谢!

最佳答案

C11支持原子操作。不幸的是,大多数编译器不支持 C11 原子,但您可以使用 GCC 4.9 来支持它们:

#include <stdatomic.h>

struct mystruct
{
_Atomic int a;
...
};

int load(struct mystruct* s)
{
return atomic_load(&s->a);
}

void store(struct mystruct* s, int value)
{
atomic_store(&s->a, value);
}

请注意,仅保护写操作是不够的。 C11 标准对此非常明确。如果两个线程可以同时访问同一内存位置,并且至少其中一个操作是写访问,则程序的行为是未定义的。这意味着您必须保护所有访问。

关于C 读取器和写入器线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23482434/

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