c - 写入通过结构传递给线程的 mmap 输出 (C)

标签 c struct pthreads

我正在开发一个项目来了解多线程并陷入编写输出的困境。

程序打开并映射一个文件,对其执行一系列操作,然后将结果输出到另一个映射的文件。参数通过结构传递给线程。

它可以很好地读取输入,但无法写入输出位置。这是(我认为)所有相关的代码段。

输入和输出的映射如下:

int * ptrin = mmap(NULL, sizeofin, PROT_READ ,MAP_SHARED , a, 0);
int * ptrout = mmap(NULL, sizeofin, PROT_READ|PROT_WRITE ,MAP_SHARED , c, 0);

结构是:

typedef struct data {
int * in;
int * out;
} threaddata;

该函数在 main 中被调用,如下所示:

    if (pthread_create(&threads[numthreads], NULL, (void *) &func, (void*) &Data) != 0) {
    perror("pthread_create() error");
    exit(1);

目前 numthreads = 1,因此尚未处理竞争条件和锁定。

函数本身处理结构如下:

void func( void *ptr ) {
threaddata *Data;
Data = (threaddata *) ptr;

for (i = 0; i < ops; i++) {
        // operations here left out
        Data->out[i] = result;
}

迭代/读取Data->first[index]处的值没有问题!只是当要写入输出位置时,它无法访问内存地址。运行程序时,错误不是段错误,而是总线错误(核心转储)。 GDB 显示此错误:

Thread 2 "prog" received signal SIGBUS, Bus error.
[Switching to Thread 0x7ffff751b700 (LWP 58056)]
0x0000000000400b99 in func (ptr=0x7fffffffdec0) at prog.c:49
49                              Data->out[i] = result;

当我尝试查看 gdb 中的数据对象时,我得到了这个:

(gdb) p Data->out[0]
Cannot access memory at address 0x7ffff7ff6000

这告诉我它发生在第一个索引处,所以这不是太多迭代或类似问题的问题。

我对线程的概念相当陌生,甚至对传递结构也很陌生。我假设它与我的结构如何存储 mmap 输出地址有关。该代码的第一个版本没有使用结构或线程,并且能够完美地写入输出文件。那么我的代码写错了,无法访问Data->out怎么办?

此外,这是我第一次在 SO 上发帖,所以我确信我的措​​辞在某些地方是错误的,并且问题的结构本来可以更好。抱歉将其分解,我只是认为这比发布整个约 200 行代码要好。我欢迎您提供任何反馈,以便下次我做得更好。谢谢大家。

最佳答案

SIGBUS 表示您正在访问文件当前大小之外的映射区域。如果您访问映射区域之外的内存,则会收到SIGSEGV

您需要做的是使用 ftruncate 将输出文件的大小调整为至少 c 字节长。

关于c - 写入通过结构传递给线程的 mmap 输出 (C),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59221148/

相关文章:

c - 在函数中传递和返回字符串指针

c++ - 结构转换为原始字符问题

c++ - 修改结构的函数不会更新结构

c++ - 多线程应用程序中的段错误

Linux 中的 Clock_nanosleep

c++ - 学习嵌入式 C/C++ 开发的最佳评估套件是什么?

c++ - C/C++ : Pointer on Pointer on structure

c - 多线程程序计算总和在笔记本电脑上比台式机运行得更快

c - 如何从主线程唤醒休眠线程?

c - 传递给函数的变量未设置为我分配给它的值