私はpthreadライブラリを使って素数を計算するプログラムを作った。 プログラムはcygwinとlinuxではうまく動作しますが、FreeBSDでは動作しません。ここでFreeBSDのpthreads
はプログラム
#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
とfinaly 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のは、このエラーが発生しているようですが、私は修正する方法を見つけ出すことはできませんですそれ。 誰も助けることができますか?
プログラムを静的にリンクしようとしましたか?おそらく、ライブラリのバージョン管理エラーです。 –