【问题标题】:[C]Malloc problems[C]Malloc 问题
【发布时间】:2014-03-19 22:02:47
【问题描述】:

我正在尝试编写一个使用一些基本线程进行分配的程序。以下是我认为导致问题的相关 sn-ps。

程序在 25 个或更少线程时运行良好,但在使用 26 个或更多线程时通常会导致段错误。这使我认为我的 malloc 语句不正确。任何人都可以将我推向正确的方向吗?如果您需要发布更多代码,我很乐意提供。

而且,这些问题只有在我在学校的学生机器上运行程序时才会出现。它似乎在我的本地机器上运行良好。有人知道为什么吗?

感谢您的宝贵时间!

...

struct thread_args {
    struct bitmap *bm;
    double xmin;
    double xmax;
    double ymin;
    double ymax;
    int max;
    int start;
    int end;
};

...

int num_threads; //Given by user input
struct bitmap *bm = bitmap_create(500, 500); //All threads share the same bitmap
int i;
pthread_t *thread_id = malloc(num_threads * sizeof(*thread_id));
struct thread_args *args = malloc(num_threads * sizeof(*args));
for (i = 0; i < num_threads; i++) { 
    args[i].bm = bm;
    args[i].xmin = xcenter-scale;
    args[i].xmax = xcenter+scale;
    args[i].ymin = ycenter-scale;
    args[i].ymax = ycenter+scale;
    args[i].max = max;
    args[i].start = bitmap_height(bm) * i / num_threads;
    args[i].end = bitmap_height(bm) * (i + 1) / num_threads;

    pthread_create(&thread_id[i], NULL, compute_image, &args[i]);
}

for (i = 0; i < num_threads; i++) {
    pthread_join(thread_id[i], NULL);
}

...

void* compute_image(void *arg)
{
    struct thread_args* args = (struct thread_args*) arg;
    int i,j;
    int width = bitmap_width(args->bm);
    int height = bitmap_height(args->bm);

    // For every pixel in the image...

    for(j=args->start;j<args->end;j++) {
        for(i=0;i<width;i++) {
            // Determine the point in x,y space for that pixel.
            double x = args->xmin + i*(args->xmax-args->xmin)/width;
            double y = args->ymin + j*(args->ymax-args->ymin)/height;

            // Compute the iterations at that point.
            int iters = iterations_at_point(x,y,args->max);
            // Set the pixel in the bitmap.
            bitmap_set(args->bm,i,j,iters);
        }
    }
    return 0;
}

...

valgrind log

==24919== 
==24919== HEAP SUMMARY:
==24919==     in use at exit: 1,000,000 bytes in 1 blocks
==24919==   total heap usage: 56 allocs, 55 frees, 1,018,884 bytes allocated
==24919== 
==24919== Searching for pointers to 1 not-freed blocks
==24919== Checked 87,112 bytes
==24919== 
==24919== 1,000,000 bytes in 1 blocks are definitely lost in loss record 1 of 1
==24919==    at 0x4A069EE: malloc (vg_replace_malloc.c:270)
==24919==    by 0x401256: bitmap_create (bitmap.c:21)
==24919==    by 0x400CEC: main (mandel.c:103)
==24919== 
==24919== LEAK SUMMARY:
==24919==    definitely lost: 1,000,000 bytes in 1 blocks
==24919==    indirectly lost: 0 bytes in 0 blocks
==24919==      possibly lost: 0 bytes in 0 blocks
==24919==    still reachable: 0 bytes in 0 blocks
==24919==         suppressed: 0 bytes in 0 blocks
==24919== 
==24919== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 6)
--24919-- 
--24919-- used_suppression:      4 U1004-ARM-_dl_relocate_object
--24919-- used_suppression:      2 glibc-2.5.x-on-SUSE-10.2-(PPC)-2a
==24919== 
==24919== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 6)

编辑:添加了 compute_image 代码和 valgrind 日志,尽管该日志缺少今天早些时候显示的错误消息。丢失的 1,000,000 字节是我所知道的。

【问题讨论】:

  • 有几个调试工具可以准确地告诉你哪里出了问题。只需谷歌“c调试工具”。调试是毕业后需要的技能
  • 我们应该假设您的所有线程都应该共享 same 位图吗?因为他们这样做。如果你认为实际的 thread proc 在这里是相关的,那么你是对的。
  • stdlib 调用可能会失败。在使用它们之前,您应该检查 malloc() 调用的返回值是否为 NULL。
  • @redFIVE 我尝试使用 GDB 和 valgrind,但我认为他们告诉我 malloc 没有分配适当的空间量。
  • @WhozCraig 啊,是的,所有线程共享同一个位图。他们处理单独的数据集和图像的一部分,因此没有竞争条件。

标签: c multithreading segmentation-fault malloc


【解决方案1】:

确保pthread_create 没有返回错误。机器对可以生成的线程数有一个全局限制,并且可能会在接近该限制的情况下波动。如果您未能生成线程,您将得到一个垃圾pthread_t,这可能会导致pthread_join 爆炸。

【讨论】:

  • 我用while (pthread_create(&amp;thread_id[i], NULL, compute_image, &amp;args[i]) != 0); 替换了pthread_create(&amp;thread_id[i], NULL, compute_image, &amp;args[i]);,它现在似乎可以工作了。这是你的意思吗?当然,我计划在某个时候使用 errno 和 strerror。
  • 我只是建议您检查错误。我会打印一条错误消息并退出而不是旋转,直到它成功。我猜每个人都在做同样的任务,并创建了很多线程。通过旋转,您的程序将等待其他人的程序完成并释放资源。但是,如果你运气不好,你的程序可能会无限期地旋转。
猜你喜欢
  • 1970-01-01
  • 2011-02-17
  • 2015-12-18
  • 1970-01-01
  • 1970-01-01
  • 2011-05-18
  • 1970-01-01
  • 1970-01-01
  • 2019-04-28
相关资源
最近更新 更多