C中的多线程使用Mutex Locks,可疑行为

时间:2017-05-18 16:33:29

标签: c multithreading pthreads mutex

目前我正在尝试c中的多线程。到目前为止情况进展顺利,但目前我遇到了一个我无法理解的问题。

为了理解使用pthread_mutex_lock和_unlock,我已经构成了一个模范和简单的场景,其中明显发生了并行。代码附后,应该适合尝试。

如下面的源代码所示,试图将其总量减少10个单位,并且一个饮酒者正在消耗将要提供的所有东西。由于杯子最多只能包含5个单位,因此使用互斥变量来调节这种示例性交换。

一切正常但我不理解控制台上的奇怪输出。输出如下所示。有没有人知道出了什么问题?或者一切都很好吗?我完全没有想法。我很感激你的帮助。 你的jBug。

Stomach: 0

Jug: 10

End: 0
call waiter 0 auf
call drinker 0 auf
Content of Cup 0 waiter Content of Cup 1
Content of Cup 1 waiter Content of Cup 2
Content of Cup 2 waiter Content of Cup 3
Content of Cup 3 waiter Content of Cup 4
Content of Cup 4 waiter Content of Cup 5
Content of Cup 5 drinker Content of Cup 4
Content of Cup 4 drinker Content of Cup 3
Content of Cup 3 drinker Content of Cup 2
Content of Cup 2 drinker Content of Cup 1
Content of Cup 1 waiter Content of Cup 1 drinker Content of Cup 2
Content of Cup 1
Content of Cup 1 waiter Content of Cup 1 drinker Content of Cup 2
Content of Cup 1
Content of Cup 1 waiter Content of Cup 1 drinker Content of Cup 2
Content of Cup 1
Content of Cup 1 waiter Content of Cup 1 drinker Content of Cup 2
Content of Cup 1
Content of Cup 1 waiter Content of Cup 1 drinker Content of Cup 2
Content of Cup 1
Content of Cup 1 drinker Content of Cup 0

Stomach: 10

Jug: 0

End: 0

随意尝试。

#include <string.h>
#include <sys/time.h>
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>

//structs für kellner
typedef struct kellnerstruct {
    int krug;
    int becherkapaz;
    pthread_mutex_t* myMutex;
} kellnerinfo;

//structs für trinker
typedef struct trinkerstruct {

    int becherkapaz;
    pthread_mutex_t* myMutex;
 trinkerinfo;

//Konkurrenzkampf findet hier statt
int becher = 0;

//param ist struct und enthät infos.
void* kellner(void* param){
    kellnerinfo* myStruct = (kellnerinfo*)param;
    while(myStruct->krug!=0){
        pthread_mutex_lock(myStruct->myMutex);
        while(myStruct->krug!=0 && myStruct->becherkapaz!=becher){

            printf("Content of Cup %d waiter ",becher);
            becher++;
            myStruct->krug--;
            printf("Content of Cup %d\n",becher);

        }
        pthread_mutex_unlock(myStruct->myMutex);
    }
    return NULL;
}

//param ist struct und enthät infos.
void* trinker(void* param){
    trinkerinfo* myStruct = (trinkerinfo*)param;
    while(myStruct->magen != 10){
        pthread_mutex_lock(myStruct->myMutex);
        while(myStruct->magen != 10 && becher!=0){

            printf("Content of Cup %d drinker ",becher);
            becher--;
            myStruct->magen++;
            printf("Content of Cup %d\n",becher);

        }
        pthread_mutex_unlock(myStruct->myMutex);
    }
    return NULL;
}

//allocate threadinfo struct
kellnerinfo* getKellnerPtr(int anzahlthreads){
    kellnerinfo* p = malloc(anzahlthreads*sizeof(kellnerinfo));
    return p;
}

//allocate threadinfo struct
trinkerinfo* getTrinkerPtr(int anzahlthreads){
    trinkerinfo* p = malloc(anzahlthreads*sizeof(trinkerinfo));
    return p;
}

int main(void) {
    /**
     * Alloziere und initialisiere struct
     *
     *
     *
     */
    //init mutex becher
    pthread_mutex_t becherSperre;

    //init structs
    kellnerinfo *kellnerPtr = getKellnerPtr(1);
    //setze Zeiger von struct auf initialisierten mutex
    kellnerPtr->myMutex = &becherSperre;
    kellnerPtr->krug = 10;
    kellnerPtr->becherkapaz = 5;

    //init structs
    trinkerinfo *trinkerPtr = getTrinkerPtr(1);
    //setze Zeiger von struct auf initialisierten mutex
    trinkerPtr->myMutex = &becherSperre;
    trinkerPtr->magen = 0;
    trinkerPtr->becherkapaz = 5;

    /**
     * Threads starten
     *
     *
     *
     */
    //Kellern Arbeitsbeginn
    printf("\nStomach: %d\n",trinkerPtr->magen);
    printf("\nJug: %d\n",kellnerPtr->krug);
    printf("\nEnd: %d\n",becher);

    int anzahlKellner = 1;
    pthread_t myKellner[anzahlKellner];
    for (int i=0; i<anzahlKellner; ++i){
        fprintf(stderr,"call waiter %d auf\n",i);
        if (pthread_create(&myKellner[i], NULL, kellner, (void*)(kellnerPtr) )) {
            fprintf(stderr, "Error creating thread\n");
            return 1;
        }
    }

    //Trinker Arbeitsbeginn
    int anzahlTrinker = 1;
    pthread_t myTrinker[anzahlTrinker];
    for (int i=0; i<anzahlTrinker; ++i){
        fprintf(stderr,"call drinker %d auf\n",i);
        if (pthread_create(&myTrinker[i], NULL, trinker, (void*)(trinkerPtr) )) {
            fprintf(stderr, "Error creating thread\n");
            return 1;
        }
    }
    /**
     * Join beider Gruppen
     *
     *
     *
     */

    for (int i=0; i<anzahlTrinker; ++i){
         //wait for the second thread to finish
        if (pthread_join(myTrinker[i], NULL)) {
            fprintf(stderr, "Error joining thread\n");
            return 2;
        }
    }

    for (int i=0; i<anzahlKellner; ++i){
         //wait for the second thread to finish
        if (pthread_join(myKellner[i], NULL)) {
            fprintf(stderr, "Error joining thread\n");
            return 2;
        }
    }

    printf("\nStomach: %d\n",trinkerPtr->magen);
    printf("\nJug: %d\n",kellnerPtr->krug);
    printf("\nEnd: %d\n",becher);
    return EXIT_SUCCESS;
}

0 个答案:

没有答案