写入通过结构 (C) 传递给线程的 mmap 输出
write to mmap'ed output passed to a thread through a struct (C)
我正在从事一个项目,以了解多线程并在编写输出时遇到困难。
程序打开并映射一个文件,对其执行一系列操作,然后将结果输出到另一个映射的文件。参数通过结构传递给线程。
它可以很好地读取输入,但无法写入输出位置。这是(我认为)所有相关的代码段。
输入和输出映射如下:
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;
}
迭代 through/reading 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 中的数据对象时,我得到:
(gdb) p Data->out[0]
Cannot access memory at address 0x7ffff7ff6000
这告诉我它发生在第一个索引处,所以它不是太多迭代或类似问题的问题。
我对线程的概念相当陌生,甚至对结构传递也很陌生。我假设它与我的结构如何存储 mmap 输出地址有关。此代码的第一个版本没有使用结构或线程,并且能够完美地写入输出文件。那么我的代码写错了,无法访问怎么办 Data->out
?
此外,这是我第一次在 SO 上发帖,所以我确定我的措辞有误,问题的结构本可以更好。很抱歉把它拆散了,我只是觉得这比发布整个 ~200 行代码要好。我欢迎您提供任何反馈,以便下次我做得更好。谢谢大家。
SIGBUS
表示您正在访问文件当前大小 之外的映射区域。如果您访问 映射区域 之外的内存,您将得到 SIGSEGV
。
您需要做的是使用 ftruncate
将输出文件的大小调整为至少 c
字节长。
我正在从事一个项目,以了解多线程并在编写输出时遇到困难。
程序打开并映射一个文件,对其执行一系列操作,然后将结果输出到另一个映射的文件。参数通过结构传递给线程。
它可以很好地读取输入,但无法写入输出位置。这是(我认为)所有相关的代码段。
输入和输出映射如下:
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;
}
迭代 through/reading 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 中的数据对象时,我得到:
(gdb) p Data->out[0]
Cannot access memory at address 0x7ffff7ff6000
这告诉我它发生在第一个索引处,所以它不是太多迭代或类似问题的问题。
我对线程的概念相当陌生,甚至对结构传递也很陌生。我假设它与我的结构如何存储 mmap 输出地址有关。此代码的第一个版本没有使用结构或线程,并且能够完美地写入输出文件。那么我的代码写错了,无法访问怎么办 Data->out
?
此外,这是我第一次在 SO 上发帖,所以我确定我的措辞有误,问题的结构本可以更好。很抱歉把它拆散了,我只是觉得这比发布整个 ~200 行代码要好。我欢迎您提供任何反馈,以便下次我做得更好。谢谢大家。
SIGBUS
表示您正在访问文件当前大小 之外的映射区域。如果您访问 映射区域 之外的内存,您将得到 SIGSEGV
。
您需要做的是使用 ftruncate
将输出文件的大小调整为至少 c
字节长。