目前我正在尝试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;
}