Skip to content

Instantly share code, notes, and snippets.

@rdnt
Created April 1, 2020 15:12
Show Gist options
  • Save rdnt/7636cec11225f14e050f0bd206bab8f1 to your computer and use it in GitHub Desktop.
Save rdnt/7636cec11225f14e050f0bd206bab8f1 to your computer and use it in GitHub Desktop.
Producer/Consumer C pthreads
// Producer / consumer example
// build with `cls && gcc -O2 -Wall -pthread main.c -o main.exe && main.exe`
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define MESSAGES 20
// global integer buffer
int global_buffer;
pthread_mutex_t buffer_mutex = PTHREAD_MUTEX_INITIALIZER;
// producer thread function
void *producer_thread(void *args) {
int i = 0;
// send messages while received count < MESSAGES
while (i < MESSAGES) {
// lock mutex
pthread_mutex_lock(&buffer_mutex);
if (global_buffer == 0) {
global_buffer++;
printf("Producer: SEND %d\n", i);
i++;
}
// unlock mutex
pthread_mutex_unlock(&buffer_mutex);
}
pthread_exit(NULL);
return 0;
}
// receiver thread function
void *consumer_thread(void *args) {
int i = 0;
// receive messages while received count < MESSAGES
while (i < MESSAGES) {
// lock mutex
pthread_mutex_lock(&buffer_mutex);
if (global_buffer > 0) {
printf("Consumer: RESV %d\n", i);
global_buffer--;
i++;
}
// unlock mutex
pthread_mutex_unlock(&buffer_mutex);
}
pthread_exit(NULL);
return 0;
}
int main() {
pthread_t producer,consumer;
// create threads
pthread_create(&producer,NULL,producer_thread,NULL);
pthread_create(&consumer,NULL,consumer_thread,NULL);
// then join threads
pthread_join(producer,NULL);
pthread_join(consumer,NULL);
return 0;
}
@mixstef
Copy link

mixstef commented Apr 1, 2020

Τι τιμές παίρνει ο global_buffer; 1 και 0 μόνο;

@rdnt
Copy link
Author

rdnt commented Apr 1, 2020

@mixstef ναι, θα δω πως μπορώ να το αλλάξω για να μην χρησιμοποιεί το content του buffer για συγχρονισμό όπως είπατε

@rdnt
Copy link
Author

rdnt commented Apr 1, 2020

Κάτι τέτοιο;

// Producer / consumer example
// build with `cls && gcc -O2 -Wall -pthread main.c -o main.exe && main.exe`
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define MESSAGES 20

// global integer buffer
int global_buffer;
int messages_count = 0;
pthread_mutex_t buffer_mutex = PTHREAD_MUTEX_INITIALIZER;

// producer thread function
void *producer_thread(void *args) {
    int i = 0;
    // send messages while received count < MESSAGES
    while (i < MESSAGES) {
        // lock mutexes
        pthread_mutex_lock(&buffer_mutex);
        if (messages_count == 0) {
            global_buffer++;
            messages_count++;
            printf("Producer: SEND %d\n", i);
            i++;
        }
        // unlock mutexes
        pthread_mutex_unlock(&buffer_mutex);
    }

    pthread_exit(NULL);
    return 0;
}

// receiver thread function
void *consumer_thread(void *args) {
    int i = 0;
    // receive messages while received count < MESSAGES
    while (i < MESSAGES) {
        // lock mutexes
        pthread_mutex_lock(&buffer_mutex);
        if (messages_count > 0) {
            printf("Consumer: RESV %d\n", i);
            messages_count--;
            i++;
        }
        // unlock mutexes
        pthread_mutex_unlock(&buffer_mutex);
    }

    pthread_exit(NULL);
    return 0;
}

int main() {
    pthread_t producer,consumer;
    // create threads
    pthread_create(&producer,NULL,producer_thread,NULL);
    pthread_create(&consumer,NULL,consumer_thread,NULL);
    // then join threads
    pthread_join(producer,NULL);
    pthread_join(consumer,NULL);
    return 0;
}

@mixstef
Copy link

mixstef commented Apr 1, 2020

Τώρα είναι σωστό. Το i και το global_buffer έχουν κάποιο overlap στο ρόλο τους ;-)

@rdnt
Copy link
Author

rdnt commented Apr 1, 2020

Κατάλαβα να μην χρησιμοποιήσουμε καθόλου το buffer για ελέγχους, οπότε θέλετε κάτι τέτοιο;

// Producer / consumer example
// build with `cls && gcc -O2 -Wall -pthread main.c -o main.exe && main.exe`
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define MESSAGES 20

// global integer buffer
int global_buffer;
int messages_count = 0;
pthread_mutex_t buffer_mutex = PTHREAD_MUTEX_INITIALIZER;

// producer thread function
void *producer_thread(void *args) {
    // int i = 0;
    // send messages while received count < MESSAGES
    while (global_buffer < MESSAGES) {
        // lock mutexes
        pthread_mutex_lock(&buffer_mutex);
        if (messages_count == 0) {
            global_buffer++;
            messages_count++;
            printf("Producer: SEND %d\n", global_buffer);
            // i++;
        }
        // unlock mutexes
        pthread_mutex_unlock(&buffer_mutex);
    }

    pthread_exit(NULL);
    return 0;
}

// receiver thread function
void *consumer_thread(void *args) {
    // int i = 0;
    // receive messages while received count < MESSAGES
    while (global_buffer < MESSAGES) {
        // lock mutexes
        pthread_mutex_lock(&buffer_mutex);
        if (messages_count > 0) {
            printf("Consumer: RESV %d\n", global_buffer);
            // global_buffer--;
            messages_count--;
            // i++;
        }
        // unlock mutexes
        pthread_mutex_unlock(&buffer_mutex);
    }

    pthread_exit(NULL);
    return 0;
}

int main() {
    pthread_t producer,consumer;
    // create threads
    pthread_create(&producer,NULL,producer_thread,NULL);
    pthread_create(&consumer,NULL,consumer_thread,NULL);
    // then join threads
    pthread_join(producer,NULL);
    pthread_join(consumer,NULL);
    return 0;
}

@mixstef
Copy link

mixstef commented Apr 1, 2020

Σωστά.

@rdnt
Copy link
Author

rdnt commented Apr 1, 2020

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment