3

在这个练习中我的头撞在墙上几个小时后,我被困在那堵墙上。首先,这是一个旨在查找和打印介于 1 和 之间的所有素数的程序ceiling,其中上限是一些用户输入。设计是实现 POSIX 线程。

在我的程序中,它成功运行,直到线程方法中的后续迭代之一。当它到达后面的迭代时,它会走到线pthread_mutex_lock(lock);并旋转,迫使我用 Ctrl+z 杀死它。我一直在使用的 2 个输入1用于线程数和10上限。这个缺陷是可重现的,因为每次我尝试它都会发生。注意:虽然这段代码应该能够实现多个线程,但我希望在添加更多线程之前让它与 1 个子线程一起正常工作。

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

int* numbermarker = NULL;
int* buffer = NULL;
int* checked = NULL;
int pullposition = 0;
int placeposition = 0;
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++;
}


void* threadmethod(){   
    int i;
    int k;
    int l;
    while(1){   
        printf("pull %d   number %d \n",pullposition, buffer[pullposition]);
        pthread_mutex_lock(lock);
        printf("FLAG\n");
        l = buffer[pullposition];
        pullposition++;
        printf("pullTWO %d   number %d \n",pullposition, buffer[pullposition-1]);
        pthread_mutex_unlock(lock);
        for(k=l+1;k<=ceiling;k++){
            if(k%l){
                if(k%2){
                    checked[k]=1;
                    placevalue(k);
                }
            }
            else{
                numbermarker[k-1] = 1;
            }
        }
        int sum=0;
        for(i=0; i<ceiling; i++){
            if(numbermarker[i]){
                checked[i] = numbermarker[i];
            }
            printf("checked|%d|%d|%d|%d|%d|%d|%d|%d|%d|%d|\n",
checked[0], checked[1], checked[2], checked[3], checked[4], checked[5], checked[6], checked[7], checked[8], checked[9]); 
            sum += checked[i];
            printf("sum %d    ceiling %d\n",sum,ceiling);
        }
        printf("number |%d|%d|%d|%d|%d|%d|%d|%d|%d|%d|\n",
numbermarker[0],    numbermarker[1],    numbermarker[2],    numbermarker[3],    numbermarker[4],    numbermarker[5],    numbermarker[6],    numbermarker[7],    numbermarker[8],    numbermarker[9]);
        if(sum == ceiling){
            return NULL;
        }
    }
}


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));
    checked = (int*)malloc(sizeof(int)*(ceiling));

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

    /*allocate space for the lock*/
    lock = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t));
    pthread_mutex_init(lock,NULL);

    for(i=0; i<ceiling; i++){
        if(i<1){
            numbermarker[i] = 1;
        }
        else{
            numbermarker[i] = 0;
        }
        checked[i]=0;
        buffer[i]=0;
        printf("%d \n",numbermarker[i]);
    }
    checked[0]=1;
    placevalue(2);
    printf("checked|%d|%d|%d|%d|%d|%d|%d|%d|%d|%d|\n", checked[0], checked[1], checked[2], checked[3], checked[4], checked[5], checked[6], checked[7], checked[8], checked[9]);

    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);
        }
    }       

    for(i=0;i<numthreads;i++){
        if(pthread_join(*tid[i], NULL)){
            printf("Error Joining with thread \n");
            exit(-1);
        }
        free(tid[i]);
    }

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

    free(buffer);
    free(numbermarker);
    buffer=NULL;
    numbermarker=NULL;
    return(0);
}
4

1 回答 1

2

我已经尝试过您的代码并在

void placevalue(int value)
{
buffer[placeposition] = value;
placeposition++;
}

placeposition超过buffer. 这会导致未定义的行为,一个非常合理的结果是互斥体的垃圾(在malloc()之后立即编辑buffer)。

最重要的是,还有一个竞争条件是placevalue(). 但是,如果您使用的是单个工作线程,那么您(还)还没有遇到它。

于 2013-04-05T17:27:05.060 回答