मेरे पास एक ऐसा प्रोग्राम है जिसमें मैं एक बहु-निर्माता, बहु-उपभोक्ता सेटिंग को लागू करने की कोशिश कर रहा हूं। मेरे पास कोड है जो अच्छी तरह से काम करता है जब मेरे पास एक उपभोक्ता और एकाधिक उत्पादक हैं, लेकिन कई उपभोक्ता धागे पेश करना कुछ अजीब मुद्दों को उठाना प्रतीत होता है।एकाधिक उत्पादक एकाधिक उपभोक्ता थ्रेड इश्यू
यहाँ मैं अभी है:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#define MAX 10
typedef struct travs {
int id;
int numBags;
int arrTime;
struct travs *next;
} travs;
travs *queue;
//travs *servicing[MAX];
int produced; // The total # of produced in the queue
pthread_mutex_t queue_lock;
//pthread_mutex_t staff_lock;
pthread_cond_t ct, cs;
int CheckIn(){
sleep(1);
if(produced != 0) return 1;
else return 0;
}
void *producerThread(void *args){
travs *traveler = (travs *)args;
// Acquire the mutex
pthread_mutex_lock(&queue_lock);
produced++;
// pthread_cond_signal(&cs);
pthread_cond_wait(&ct, &queue_lock);
printf("Producer %d is now checked in at time %d.\n", queue->id, (1+queue- >arrTime));
queue = queue->next;
pthread_mutex_unlock(&queue_lock);
return;
}
int Producer(int id, int numBags, int arrTime){
int ret;
pthread_t ttid;
travs *traveler = malloc(sizeof(travs));
traveler->id = id;
traveler->numBags = numBags;
traveler->arrTime = arrTime;
sleep(arrTime);
pthread_mutex_lock(&queue_lock);
if(queue != NULL) {
travs *check_in = malloc(sizeof(travs));
check_in = queue;
while(check_in->next != NULL){
check_in = check_in->next;
}
check_in->next = traveler;
}
else { queue = traveler; }
pthread_mutex_unlock(&queue_lock);
// Create a new traveler thread
ret = pthread_create(&ttid, NULL, producerThread, (void *)traveler);
// Check if thread creation was successful
if(ret == 0) {
printf("Producer %d has entered the check-in line at time %d; s/he is at position %d and has %d bags.\n", id, arrTime, produced, numBags);
pthread_cond_signal(&cs);
return 0;
}
else return -1;
}
void *consumerThread(void *arg){
int i = 0; // travelers serviced
char *name = (char *)arg;
while(1) { // run iteratively
// If 20 producers have been served, the consumer's work is done.
if(i == 20) {
printf("Consumer %s's service has completed!\n", name);
pthread_exit(NULL);
}
// Sleep for 10s if 5 travelers have been checked in
if (((i+1) % 5) == 0) {
// Wake up sleeping travelers
printf("Consumer %s is taking a break.\n", name);
sleep(2);
printf("Consumer %s's break is over.\n", name);
}
if(CheckIn()) {
pthread_mutex_lock(&queue_lock);
int j = 1;
pthread_cond_wait(&cs, &queue_lock);
printf("Producer %d presents ticket to consumer %s.\n", queue->id, name);
printf("Consumer %s gives boarding pass to producer %d.\n", name, queue->id);
while(j <= queue->numBags){
printf("Consumer %s checks in bag %d for producer %d; baggage tag is _X_.\n", name, j, queue->id);
j++;
}
// Signal producer being serviced that their check in is complete.
i++;
pthread_mutex_unlock(&queue_lock);
produced--;
pthread_cond_signal(&ct);
}
sleep(3);
}
}
int Consumer(char *Name) {
sleep(5);
int ret;
pthread_t stid;
// Create a staff thread
ret = pthread_create(&stid, NULL, consumerThread, (void *)Name);
// Acquire the lock
if(ret == 0) {
printf("Producer %s's service has begun!\n", Name);
return 0;
}
else return -1;
}
int main() {
int ret = 0;
char *staff_name = malloc(sizeof(char));
int staff_check = 0;
int trav_check = 0;
int id;
int bagnum;
int travtime;
FILE *consumer_fp;
FILE *producer_fp;
queue = malloc(sizeof(travs));
queue = NULL;
/*while(ret < 10){
servicing[ret] = malloc(sizeof(travs));
servicing[ret] = NULL;
}*/
// Initilize mutexes
pthread_mutex_init(&queue_lock, NULL);
//pthread_mutex_init(&staff_lock, NULL);
// Initialize condition variables
pthread_cond_init(&ct, NULL);
pthread_cond_init(&cs, NULL);
// Open the file so we can start reading from it
consumer_fp = fopen("staff.txt", "r");
producer_fp = fopen("travelers.txt", "r");
staff_check = fscanf(consumer_fp, "%s", staff_name);
trav_check = fscanf(producer_fp, "%d %d %d", &id, &bagnum, &travtime);
while(1){
K:
while(staff_check == 1) {
Consumer(staff_name);
staff_check = fscanf(consumer_fp, "%s", staff_name);
goto L;
}
L:
while(trav_check == 3) {
Producer(id, bagnum, travtime);
trav_check = fscanf(producer_fp, "%d %d %d", &id, &bagnum, &travtime);
goto K;
}
pthread_exit(NULL);
}
}
इस सेटिंग में, हर निर्माता धागा लौटने से पहले केवल थोड़े समय के लिए रहता है, और वैश्विक कतार में एक नया तत्व जोड़ के अलावा कोई वास्तविक गणना में ही करता है और कुछ उपयुक्त समय आउटपुट लाइनें।
हालांकि, जब मैं कई उत्पादकों को पेश करता हूं, केवल अंतिम निर्माता धागा कुछ भी करता है।
मैं क्या समझ में आता है से, मैं निम्नलिखित की जरूरत है:
i) इंतज़ार कर करने के लिए चेक-इन किया और निर्माता रहे हैं जो वर्तमान में किया जा रहा चेक-इन किया उत्पादकों के लिए अलग कतार (travs के रूप में बाहर टिप्पणी की * सर्विसिंग [मैक्स] उपरोक्त)
ii) उपभोक्ताओं के लिए एक अलग म्यूटेक्स।
हालांकि, मुझे यकीन नहीं है कि इसे कैसे कार्यान्वित किया जाए। यह विचार मेरे मन में था:
चेकइन() एक निर्माता धागा और प्रतिलिपि * कतार में * सर्विसिंग [i] (उपभोक्ता सूत्र में)।
सेट कतार = कतार-> अगला (निर्माता थ्रेड में)।
लेकिन, मैं कैसे सुनिश्चित कर सकते हैं जब मैं पर कॉपी * कतार यह पहले से ही एक कदम उन्नत नहीं होगा कि कि है? क्या मैं वर्तमान में रखे गए थ्रेड से अलग लॉक के साथ प्रतीक्षा थ्रेड सिग्नल कर सकता हूं? और, सबसे महत्वपूर्ण बात यह है कि मेरे पास अलग-अलग उपभोक्ता धागे अलग-अलग यात्री धागे को कैसे संसाधित करेंगे?
किसी भी सहायता की सराहना की जाएगी!
travs *traveler = malloc(sizeof(travs));
traveler = (travs *)args;
मैं के बारे में "क्या मेमोरी लीक के बारे में इतना बुरा है?" विस्तार में जाने के लिए नहीं जा रहा हूँ:
'travs * traveler = malloc (sizeof (travs)); यात्री = (travs *) तर्क; 'एक स्मृति रिसाव है ... – Sebivor
आह, पकड़ के लिए धन्यवाद। मैं वहां एक मुफ्त लाइन जोड़ दूंगा। – user991710