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

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

我正在研究一个项目,以了解多线程以及如何编写输出内容。

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

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

输入和输出的映射如下:

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;

该函数在主体中这样调用:

    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]处的值没有问题!仅当要写入输出位置时,它无法访问内存地址。运行该程序时,错误不是段错误,而是Bus error (core dumped)。 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中的Data对象时,我得到了:

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

这告诉我,它恰好在第一个索引处发生,因此,迭代次数过多或类似的问题都不是问题。

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

而且,这是我第一次在SO上发帖,所以我确信我的措​​辞在某处是错误的,并且本来可以更好地解决这个问题。对不起,我把它分解了,我想比发布整个〜200行代码更好。欢迎您提供任何反馈意见,以便下次更好。谢谢大家。

c struct pthreads
1个回答
1
投票

SIGBUS表示您正在访问文件的当前大小外部的映射区域。如果要访问mapped area以外的内存,则会得到SIGSEGV

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

© www.soinside.com 2019 - 2024. All rights reserved.