【问题标题】:pthreads on FreeBSDFreeBSD 上的 pthread
【发布时间】:2014-12-09 18:32:07
【问题描述】:

我制作了一个使用 pthread 库计算素数的程序。 该程序在 cygwin 和 linux 下表现良好,但在 FreeBSD 下表现不佳。

这是程序

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <math.h>

#define NUMTHREADS 5 
#define N 10000 

typedef struct
{
    int start;
    int end;
}DISTANCE;

int arr[N];

pthread_mutex_t mutex;

void *sieve(void* s)
{
    int start,end,k,i,j;
    DISTANCE* d = (DISTANCE*)s;
    start = d->start;
    end = d->end;   
    for(i=start;i<end;i++)
    {

        if(arr[i]==0)
        {
            k = i;
            for(j=2*k;j<N+1;j+=i)
            {

                    pthread_mutex_lock(&mutex);
                    arr[j] = 1;
                    pthread_mutex_unlock(&mutex);

            }
        }
    }
    pthread_exit(NULL);
}
void *fill_array(void* f)
{
    int i;
    arr[0] = 1;
    arr[1] = 1;

    for(i=2;i<N;i++)
    {
        arr[i] = 0;
    }
    pthread_exit(NULL);
}
int main(int argc, char **argv)
{

    int div;
    int status;
    int i;
    int count = 0;
    int nums = 0;   

    pthread_t threads[NUMTHREADS];
    DISTANCE dist[NUMTHREADS];

    #ifdef NORMAL_FILL_ARRAY
    arr[0] = 1;
    arr[1] = 1;

    for(i=2;i<N;i++)
    {
        arr[i] = 0;
    }
    #endif

    #ifdef THREAD_FILL_ARRAY
    pthread_t p_arr;
    pthread_create(&p_arr, NULL, fill_array, (void *) NULL);
    pthread_join(p_arr,NULL);
    #endif

    div = ((int)sqrt(N)+1)/NUMTHREADS;
    pthread_mutex_init(&mutex, NULL);

    for(i=0;i<NUMTHREADS;i++)
    {
        if(i==0)
        {
            dist[i].start = 2;
            dist[i].end = 2 + div;
        }
        else if(i==NUMTHREADS-1)
        {
            dist[i].start = dist[i-1].end;
            dist[i].end = (int)sqrt(N)+1;
        }
        else
        {
            dist[i].start = dist[i-1].end;
            dist[i].end = dist[i].start + div;
        }
        pthread_create(&threads[i],NULL,sieve,(void *)&dist[i]);
    }

    for(i=0;i<NUMTHREADS;i++)
    {
        if(pthread_join(threads[i],(void **)&status)!=0)
            printf("pthread_join error");
    }   
    pthread_mutex_destroy(&mutex);

    /*slower with print*/
    for(i=0;i<N;i++)
        {
                if(arr[i]==0)
                {
                        #ifdef PRINT
                        printf("%d\t",i);
                        count++;
                        #endif
                        nums++;
                }
                #ifdef PRINT
                if(count==10)
                {
                        printf("\n");
                        count = 0;
                }
                #endif
        }
        #ifdef PRINT
        printf("\n");
        #endif
    printf("%d: prime numbers found!\n",nums);
    pthread_exit(NULL);
    return 0;
}

Makefile

COMPILER=gcc
LIBS=-lpthread -lm
PRINT=-D PRINT
NORMAL=-D NORMAL_FILL_ARRAY
THREAD=-D THREAD_FILL_ARRAY

default:
    $(COMPILER) $(NORMAL) p_sieve.c -o p_sieve $(LIBS)
threadfill:
    $(COMPILER) $(THREAD) p_sieve.c -o p_sieve $(LIBS)
default_p:
    $(COMPILER) $(NORMAL) $(PRINT) p_sieve.c -o p_sieve $(LIBS)
threadfill_p:
    $(COMPILER) $(NORMAL) $(PRINT) p_sieve.c -o p_sieve $(LIBS)
debug:
    $(COMPILER) $(NORMAL) -g p_sieve.c -o p_sieve $(LIBS)
clean:
    rm p_sieve

最后是 gdb 输出

This GDB was configured as "i386-marcel-freebsd"...
(gdb) r
Starting program: /root/lab/src/sieve/p_sieve 
[New LWP 100060]
[New Thread 28201140 (LWP 100060)]
[New Thread 28218140 (LWP 100085)]
[New Thread 28217ec0 (LWP 100090)]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 28218140 (LWP 100085)]
0x28098f1f in pthread_mutex_unlock () from /lib/libthr.so.3

似乎 pthread_mutex_unlock 产生了这个错误,但我不知道如何修复它。 有人可以帮忙吗?

【问题讨论】:

  • 你试过静态链接程序吗?可能是库版本控制错误。

标签: multithreading pthreads freebsd primes


【解决方案1】:

如果不检查源代码的详细信息——你是否有可能在某处破坏了你的记忆——这可以解释奇怪的 SIGSEGV。否则,我看不出 pthread_mutex_unlock() 会核心转储的原因。

也许尝试删除所有数组操作?或者在那里添加一些额外的边界检查?

【讨论】:

  • 这就是问题所在。经过一些迭代后,我正在读取一个超出范围的值。
【解决方案2】:

我不记得确切并且手头没有 FreeBSD,但尝试使用 -pthread 标志进行编译。

【讨论】:

  • 那没有帮助。问题依然存在。
  • @wallee:能否请您提供您现在用来编译程序的命令(由make 打印)。另外,您能否查看 pthread_t 结构(我不记得它是否是那里的结构)是否被破坏(是否有人踩到内存)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-26
  • 2014-01-23
  • 2018-02-20
  • 2011-05-30
  • 2013-09-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多