2

私は、このセグメンテーション違反の原因を突き止めようと、数時間壁に頭を悩ませてきました。

segfault がpthread_mutex_lock(lock)行 (38) で一貫して発生することがわかりました。ロックを囲む 2 つの印刷ステートメントを配置しましたが、そのうちの 1 つだけが印刷されます。これは、セグメンテーション違反がその命令で発生すると結論付ける正当な理由です。

ミューテックス ロックを正しく使用していますか、それとも配列(buffer[]を間違えていますnumbermarker[]か?

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

int* numbermarker = NULL;
int* buffer = NULL;
int pullposition = 0;
int placeposition = 1;
pthread_mutex_t *lock;
int ceiling;

/*This method places one of the primes in the buffer. It 
offers a safe way to manage where the next value will be placed*/
void placevalue(int value)
{
    buffer[placeposition] = value;
    placeposition++;
}

/*This method pulls the next prime and increments to the next prime in the list*/
int takevalue()
{
    pullposition++;
    return buffer[pullposition-1];
}


void* threadmethod()
{   
    int k;
    int l;
    int firstval;
    while(1)
    {
        while(numbermarker[buffer[pullposition]-1]==0)
        {   
            printf("flag1 \n");
            pthread_mutex_lock(lock);
            printf("flag2 \n");
              numbermarker[buffer[pullposition]-1] = 1;
              l = takevalue();
            pthread_mutex_unlock(lock);
            firstval = 1;
            for(k=l+1;k<=ceiling;k++)
            {
                if(k%l != 0)
                {
                    if(firstval)
                    {
                        placevalue(k);
                        firstval = 0;
                    }
                }
                else
                {
                    numbermarker[k-1] = 1;
                }
            }
        }
    }
}


int main()
{
int numthreads;
int i;

printf("Enter number of threads: \n");
scanf("%d", &numthreads);

printf("Enter the highest value to check \n");
scanf("%d", &ceiling);

    /* This will hold 1's and 0's.
        1 = number has been checked or is
            confirmed not to be a prime
        0 = number is a possible prime

    The idea behind these values is that the next
    prime can always be identified by the 0 with
    the lowest index*/
numbermarker = (int*)malloc(sizeof(int)*(ceiling));

    /*This will hold the primes as they are found*/
buffer = (int*)malloc(sizeof(int)*(ceiling));

for(i=0; i<ceiling; i++)
{
    if(i<1)
    {
        numbermarker[i] = 1;
    }
    else
    {
        numbermarker[i] = 0;
    }

    buffer[i]=0;
    printf("%d \n",numbermarker[i]);
}

placevalue(2);

pthread_t **tid = (pthread_t **) malloc(sizeof(pthread_t *) * numthreads);


for(i=0;i<numthreads;i++)
{

    tid[i] = (pthread_t *) malloc(sizeof(pthread_t));
}

for(i=0;i<numthreads;i++)
{

    if(pthread_create(tid[i],
              NULL,
              threadmethod,
              NULL))
    {

        printf("Could not create thread \n");
        exit(-1);
    }
}       


int not_done = 1;
int sum;
while(not_done)
{
    sum = 0;    
    for(i=0; i<ceiling; i++)
    {
        sum += numbermarker[i];
    }
    if(sum == ceiling)
      not_done = 0;
}
for(i=0;i<numthreads;i++)
{
    if(pthread_join(*tid[i], NULL))
    {
        printf("Error Joining with thread \n");
    }
    free(tid[i]);
}
free(tid);




for(i=0;i<ceiling;i++)
{
    if(buffer[i] != 0);
        printf("%d \n", i);
}
free(buffer);
free(numbermarker);
buffer=NULL;
numbermarker=NULL;


return(0);

}

4

1 に答える 1

5

lock初期化されていないポインタです。メモリを割り当ててから、ロックする前にミューテックスを初期化する必要があります。最も簡単な修正は変更することです

pthread_mutex_t *lock;

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

そして(lockもはやポインタではないので)

pthread_mutex_lock(lock);
....
pthread_mutex_unlock(lock);

pthread_mutex_lock(&lock);
....
pthread_mutex_unlock(&lock);
于 2013-04-05T07:52:40.813 に答える