使用共享内存运行程序的问题;有时会出现故障; shmmax和shmall有什么关系吗?

时间:2010-11-20 04:40:59

标签: c linux memory memory-management linux-kernel

HI,

我有一个程序,其中一个主进程产生N个工人,他们将反转每个图像的每一行,最后给我一个倒像。该程序使用共享内存和posix信号量,未命名的sems,更具有特殊性,我在termin()函数中使用shmctl和IPC_RMID以及sem_close和sem_destroy。 但是,当我多次运行程序时,有时它会给我一个分段错误,并且在第一个shmget中。我已经在内核中修改了我的shmmax值,但我不能对shmall值做同样的事情,我不知道为什么。

有人可以帮帮我吗?为什么会这样,为什么不是一直这样?代码看起来很好,给了我想要的东西,高效等等......但有时我必须重新启动Ubuntu才能再次运行它,甚至认为我可以释放资源。

请赐教!

编辑:

以下是运行代码+ makefile所需的3个文件:
http://pastebin.com/JqTkEkPv
http://pastebin.com/v7fQXyjs
http://pastebin.com/NbYFAGYq

http://pastebin.com/mbPg1QJm

你必须像这样运行./invert someimage.ppm outimage.ppm (现在请小试一下)

以下是一些可能很重要的值:

$ipcs -lm
------ Shared Memory Limits --------
max number of segments = 4096
max seg size (kbytes) = 262144
max total shared memory (kbytes) = 8388608
min seg size (bytes) = 1

$ipcs -ls

------ Semaphore Limits --------
max number of arrays = 128
max semaphores per array = 250
max semaphores system wide = 32000
max ops per semop call = 32
semaphore max value = 32767
编辑:seg故障解决了!我在共享内存中分配了一个**数组,这有点奇怪。所以,我只为*数组分配了段而且是voilà。如果需要,请检查新代码和评论。

2 个答案:

答案 0 :(得分:3)

如果您的所有sem_t POSIX信号量都未命名,则只能使用sem_initsem_destroy,而不能使用sem_close

答案 1 :(得分:1)

现在您发布了代码,我们可以多说一点。

如果没有详细阅读,我认为main的清理阶段看起来很可疑。事实上,在我看来,您的所有工作进程也将执行清理阶段。

在分叉之后,你应该更清楚地区分main做什么和做什么。备选方案:

  • 您的主要流程可能就是 wait工人的pid 然后才做其余的事 处理和清理。
  • 所有工作流程都可以 在致电之后返回main worker
  • 在工作人员结束时致电exit 功能

代码更新后修改:

我认为更好的解决方案是为所有流程执行经典wait

现在让我们来看看你的工作流程。实际上这些永远不会终止,break循环中没有while (1)语句。我认为正在发生的事情是,一旦没有更多的工作要做,

  • 工人陷入困境 sem_wait(sem_remaining_lines)
  • 您的主要流程会收到通知 终止
  • 它会破坏sem_remaining_lines
  • 工作人员从sem_wait返回 并继续
  • 因为mutex3已经存在 销毁(或甚至未映射)等待它返回 立即
  • 现在它尝试访问数据,并且 取决于main的距离 进程破坏了数据 是否映射和工人 崩溃(或不崩溃)

你可以看到你在那里遇到很多问题。我要做的是清理这个烂摊子

  • waitpid在销毁共享之前 数据
  • sem_trywait而不是1 in while (1)。但也许我并没有完全理解你的控制流程。在任何情况下,给他们一个终止条件。
  • 捕获系统的所有回报 函数,尤其是sem_t 家庭。这些可以被中断 IO,所以你肯定必须 检查这些EINTR