#include #include #include #include #include #include "buff.h" #define ERR_PTR ((void *)1) #define VOID_CAST(num) ((void *) num) #define N_PRODUCERS 16 #define N_CONSUMERS 1 #define KEY_LEN 32 // len in chars const char key_syms[] = "abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ" "1234567890"; #define ALPHABET_SIZE (sizeof(key_syms) - 1) pthread_t consumers[N_CONSUMERS] = {0}; pthread_t producers[N_PRODUCERS] = {0}; /** * Создает "ключи" - наборы "случайных" символов из * списка допустимых */ void get_key(char key_dest[KEY_LEN]) { for (size_t i = 0; i < KEY_LEN; i++) { size_t sym_idx = rand() % ALPHABET_SIZE; key_dest[i] = key_syms[sym_idx]; } } volatile bool run = true; void *producer_routine(void *arg) { size_t pidx = (size_t) arg; struct message msg = {0}; while (run) { get_key(msg.msg); if (buf_push(&msg)) pthread_exit(ERR_PTR); printf("[p%lu] pushed new key\n", pidx); sleep(1); } pthread_exit(NULL); } void *consumer_routine(void *arg) { size_t cidx = (size_t) arg; struct message msg = {0}; while (run) { if (buf_consume(&msg)) pthread_exit(ERR_PTR); printf("[c%lu] obtained key %s\n", cidx, msg.msg); sleep(1); } pthread_exit(NULL); } int main() { if (buf_init()) { printf("failed to init work buffer\n"); return EXIT_FAILURE; } for (size_t i = 0; i < N_PRODUCERS; i++) { if (pthread_create(&producers[i], NULL, producer_routine, VOID_CAST(i))) { printf("Failed to create enough consumer threads\n"); return EXIT_FAILURE; } } for (size_t i = 0; i < N_CONSUMERS; i++) { if (pthread_create(&consumers[i], NULL, consumer_routine, VOID_CAST(i))) { printf("Failed to create enough consumer threads\n"); return EXIT_FAILURE; } } sleep(10); run = false; void *ret = NULL; for (size_t i = 0; i < N_PRODUCERS; i++) { if (pthread_join(producers[i], &ret)) { printf("failed to join producer"); return EXIT_FAILURE; } } for (size_t i = 0; i < N_CONSUMERS; i++) { if (pthread_join(consumers[i], &ret)) { printf("failed to join consumer"); return EXIT_FAILURE; } } // не используем разделяемые ресурсы, так что код возврата // можно игнорировать, linux справится buf_deinit(); return EXIT_SUCCESS; }