-2

c で 10 個の pthreads を作成していますが、何らかの理由でそれらが順次実行されているようです。各スレッドに ID を割り当て、スレッドごとに ID を配列に 10 回書き込みます。10 個のスレッドの書き込みが完了したら、配列を解析します。配列を通過すると、各スレッドの ID が連続して表示されます。配列には 100 個の ID が書き込まれており、それらはすべて連続して書き込まれています。私が期待しているのは、競合状態が発生して、一部の ID が上書きされることです。また、すべての ID が配列に連続して現れるとは思っていません。

コードは次のとおりです。

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

//Count variabes and flags
int noItemsToProduce = 10; //Number of items produced by a single thread.
int totalItemsToProduce = 100; //Number of items produced by 10 threads.
int noItemsConsumed = 0; //Number of items removed by consumer.
int done = 0; //Flag used to know when to terminate.
int queueEmpty = 0;
void *res; //Stores the result from the thread.

//Queue Variables
int *queueArray;
int front = 0;
int back = -1;

void enqueue(int item)
{
    if(back < totalItemsToProduce-1)
    {
        queueArray[++back] = item;
    }
}

void dequeue()
{
    if(front<=back)
    {
        front++;
    }
    else
    {
        queueEmpty = 1;
        front=0;
        back=-1;
    }
}

static void *producer(void *arg)
{
    int i;
    int id = strtol(arg,NULL,0);
    for(i=0;i<noItemsToProduce;i++)
    {
        enqueue(id);
    }
}

static void *consumer(void *arg)
{
    while(!done || !queueEmpty)
    {
        printf("Dequeuing item with id = %d at pos = %d.\n",queueArray[front],front);
        dequeue();
        noItemsConsumed++;
    }
}

int main(int argc,char *argv[])
{
    //The user needs to specify the number of ints each of the 10
    //producers will produce.
    if (argc!=2)
    {
        printf("Usage: %s #-items-for-each-producer\n",argv[0]);
        return -1;
    }
    else
    {
        noItemsToProduce = strtol(argv[1],NULL,0);
        totalItemsToProduce = 10*noItemsToProduce;
        queueArray = (int *)malloc(sizeof(int)*totalItemsToProduce);
    }

    //Declarations.
    queueArray = (int *)malloc(sizeof(int)*(10*noItemsToProduce));
    pthread_t p1;
    pthread_t p2;
    pthread_t p3;
    pthread_t p4;
    pthread_t p5;
    pthread_t p6;
    pthread_t p7;
    pthread_t p8;
    pthread_t p9;
    pthread_t p10;
    pthread_t c;

    //Start producer and consumer threads.
    pthread_create(&p1,NULL,producer,"1");
    pthread_create(&p2,NULL,producer,"2");
    pthread_create(&p3,NULL,producer,"3");
    pthread_create(&p4,NULL,producer,"4");
    pthread_create(&p5,NULL,producer,"5");
    pthread_create(&p6,NULL,producer,"6");
    pthread_create(&p7,NULL,producer,"7");
    pthread_create(&p8,NULL,producer,"8");
    pthread_create(&p9,NULL,producer,"9");
    pthread_create(&p10,NULL,producer,"10");

    //Wait until all of the producers finish producing.
    pthread_join(p1,&res);
    pthread_join(p2,&res); 
    pthread_join(p3,&res); 
    pthread_join(p4,&res); 
    pthread_join(p5,&res); 
    pthread_join(p6,&res); 
    pthread_join(p7,&res); 
    pthread_join(p8,&res); 
    pthread_join(p9,&res); 
    pthread_join(p10,&res); 

    //We're done producing so let the consumer know.
    done = 1;
    pthread_create(&c, NULL, consumer, queueArray);
    pthread_join(c,&res);   
    printf("Total items produced = %d.\n",10*noItemsToProduce);
    printf("Total items consumed = %d.\n",noItemsConsumed-1);

    return 0;
}
4

4 に答える 4

3

競合状態があります。OS の pthreads 実装のアーティファクトに見られるもの。各スレッドがより多くの作業を行うようにすると (理想的には、より多くの作業を行うようにすると)、アーティファクトが消えることがわかります。

于 2013-02-16T06:15:22.610 に答える
2

pthreadsスレッドがどのようにスケジュールされるかについての保証はありません。多くの作業を行わない場合、OS は各スレッドを順番にスケジュールして完了させることができます。

本当に競争させたい場合は、 のような忙しい仕事をさせてくださいfor(i=0; i<100000000; i++) write_to_array;。もちろん、これでも実際にレースが行われることを保証するものではありませんが、ほとんどのスケジューラでオッズが改善されます.

于 2013-02-16T06:14:11.280 に答える
1

4 人の射手にそれぞれ弓と矢を持ってきてもらい、野原に行き、的を狙って一列に並んで発砲すると、同時に 2 本の矢が空中に飛んでいる可能性がありますが、その可能性はあまり高くありません。ほとんどの時間は、スレッドの作成と破棄に費やされます。2 人が同時に配列にアクセスする可能性はほぼゼロです。

于 2013-02-16T06:18:02.833 に答える
0

問題は何ですか?

「問題」はこれです:

また、すべての ID が配列に連続して現れるとは思っていません。

私はe。実装の詳細について期待したり、仮定したりします。

于 2013-02-16T06:14:08.480 に答える