Ich habe eine Lösung der Produzent/Verbraucher-Problem in C mit Pthreads und Semaphoren implementiert.Langsam Pthread Verbraucher
Mein Haupt-Thread ist der Produzent und ich starte N Consumer-Threads.
Mein Code ist:
typedef struct
{
int buf[BUFSIZE]; /* shared var */
int in; /* buf[in%BUFSIZE] is the first empty slot */
int out; /* buf[out%BUFSIZE] is the first full slot */
sem_t full; /* keep track of the number of full spots */
sem_t empty; /* keep track of the number of empty spots */
pthread_mutex_t mutex; /* enforce mutual exclusion to shared data */
} CONSUMER_STRUCT;
CONSUMER_STRUCT shared;
Dies ist der Code für jedes meiner Verbraucher-Themen:
void *Consumer(void *arg)
{
int fd, workerID, i, hit=0;
workerID = *(int *)arg;
for (;;) {
sem_wait(&shared.full);
pthread_mutex_lock(&shared.mutex);
fd = shared.buf[shared.out];
printf("\n[C%d] Consumed. I got %d ...Valor do buffer: %d na posição %d\n\n\n", workerID, fd, shared.buf[shared.out], shared.out);
ftp(fd, hit);
shared.buf[shared.out] = 0;
shared.out = (shared.out+1)%BUFSIZE;
fflush(stdout);
printf("\n\n\n\nEstado do buffer:\n\n\n\n");
for (i = 0; i < BUFSIZE; i++) {
//printf("%d ", shared.buf[i]);
}
/* Release the buffer */
pthread_mutex_unlock(&shared.mutex);
/* Increment the number of full slots */
sem_post(&shared.empty);
hit++;
}
return NULL;
}
Und das ist der Code für meinen Produzenten thread:
item = socketfd;
sem_wait(&shared.empty);
pthread_mutex_lock(&shared.mutex);
shared.buf[shared.in] = item;
shared.in = (shared.in + 1) % BUFSIZE;
fflush(stdout);
pthread_mutex_unlock(&shared.mutex);
sem_post(&shared.full);
Alles funktioniert ordnungsgemäß, aber das Bereitstellen von 22 Dateien dauert ungefähr 20 Sekunden, während das Erstellen eines Threads pro Anfrage etwa 2 dauert Sekunden! Dies scheint einen Thread nach dem anderen auszuführen, und ich möchte sie alle "gleichzeitig" ausführen.
Mache ich etwas falsch in meinem Implementierungsansatz?
Ihre Verbraucher halten den Mutex während effektiv ihrer gesamten Operation. Sie führen Single-Threaded mit Synchronisierungsoverhead aus. – EOF
Ich habe verstanden, was du meintest! Was sollte der richtige Ansatz für dieses Problem sein? – rafaelcpalmeida
Nehmen wir einmal an, dass 'ftp()' in 'Consumer()' die Ausführungszeit des Konsumenten dominiert. Nehmen wir weiter an, dass 'ftp()' Thread-sicher ist. Dann können Sie einfach 'ftp()' unterhalb des 'pthread_mutex_unlock()' verschieben und gleichzeitig ausführen. – EOF