У меня есть код, написанный на C, я хотел бы спросить вас о:
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <pthread.h>
#define COLOR_YELLOW "\x1b[33m"
#define COLOR_RED "\x1b[31m"
#define COLOR_RESET "\x1b[0m"
int tests = 3;
int running_servers;
int servers;
int clients;
int max_clients;
int current_id = 0;
int clients_handled = 0;
void *server(void *arg);
void *client(void *arg);
pthread_mutex_t server_mutex;
pthread_mutex_t client_mutex;
pthread_cond_t order_cond;
pthread_cond_t getting_clients;
pthread_cond_t full;
int main(int argc, char *argv[]) {
if(argc != 4) { printf("expected 3 arguments"); return 1; }
// INIT
servers = atoi(argv[1]);
running_servers = atoi(argv[1]);
clients = atoi(argv[2]);
max_clients = atoi(argv[3]);
pthread_mutex_init(&server_mutex, NULL);
pthread_mutex_init(&client_mutex, NULL);
pthread_cond_init(&order_cond, NULL);
pthread_cond_init(&getting_clients, NULL);
pthread_cond_init(&full, NULL);
pthread_t *server_thread = calloc(servers, sizeof(pthread_t));
pthread_t *client_thread = calloc(clients, sizeof(pthread_t));
// CREATING CLIENT THREADS
int *arg;
for (int i = 0; i < clients; i++) {
arg = malloc(sizeof(int));
*arg = i;
if (pthread_create(&client_thread[i], NULL, client, (void *) arg))
perror("pthread_create error for passenger");
}
// CREATING SERVER THREADS
for (int i = 0; i < servers; i++) {
arg = malloc(sizeof(int));
*arg = i;
if (pthread_create(&server_thread[i], NULL, server, (void *) arg))
perror("pthread_create error for car");
}
// JOINING ENDING THREADS
for (int i = 0; i < servers; i++)
if (pthread_join(server_thread[i], NULL)) perror("pthread_join error for car");
for (int i = 0; i < clients; i++)
if (pthread_join(client_thread[i], NULL)) perror("pthread_join error for passenger");
return 0;
}
void *server(void *arg) {
int id = *(int *) arg;
printf(COLOR_RED "SERVER: %d" COLOR_RESET " start working\n", id);
while (tests--) {
// ONLY ONE SERVER CAN WORK - SERVERS ARE RUN IN ORDER
pthread_mutex_lock(&server_mutex);
while (id != current_id)
pthread_cond_wait(&order_cond, &server_mutex);
printf(COLOR_RED "SERVER: %d" COLOR_RESET " starts\n", id);
printf(COLOR_RED "SERVER: %d" COLOR_RESET " gets clients \n", id); // server gets clients
pthread_cond_broadcast(&getting_clients);
pthread_cond_wait(&full, &client_mutex); // server is waiting for signal (from any client)
printf(COLOR_RED "SERVER: %d" COLOR_RESET " is full \n", id); // that he has max number of clients
printf(COLOR_RED "SERVER: %d" COLOR_RESET " stops \n", id);
current_id = (current_id + 1) % servers;
pthread_mutex_unlock(&server_mutex);
pthread_cond_broadcast(&order_cond);
}
running_servers -= 1;
return NULL;
}
void *client(void *arg) {
int id = *(int *) arg;
printf(COLOR_YELLOW "CLIENT: %d" COLOR_RESET " starts\n", id);
while (running_servers) {
pthread_mutex_lock(&client_mutex); // only one client at the time (should be)
pthread_cond_wait(&getting_clients, &client_mutex);
printf(COLOR_YELLOW "CLIENT: %d" COLOR_RESET " has access to server %d\n", id,current_id);
clients_handled++;
for (int j = 0; j < 10; j++) { // client writes some numbers
printf("%d: ", id);
for (int i = 0; i < 10; i++) {
printf("%d ", 10 * j + i);
}
printf("\n");
}
if(clients_handled == max_clients) { // client sends signal he is the last one server can handle
printf(COLOR_YELLOW "CLIENT: %d" COLOR_RESET " server %d is full, shifting to next server\n", id, current_id);
clients_handled = 0;
pthread_cond_signal(&full);
}
pthread_mutex_unlock(&client_mutex);
}
return NULL;
}
это не красиво, но работает (вроде).
Как это работает: Программа получает 3 аргумента: количество серверов, количество клиентов, максимальное количество клиентов на сервере.У нас есть серверы и клиенты, созданные как потоки.На данный момент должны быть активны один клиент и один сервер (для этого используются мьютексы server_mutex и client_mutex).Информация о широковещании сервера, он активен (условие get_clients), клиенты запускаются один рядом друг с другом, клиент записывает некоторые числа, если он последний, который сервер может обработать, он сигнализирует об этом (полное условие), и сервер переключается на следующий.Надеюсь, у вас нет проблем с его запуском (как я уже писал, это работает - вроде как).
Что не работает
похоже, что server_mutex выполняет свою работу, серверы запускаются один за другим, но client_mutex этого не делает, и я не знаю, почему иногда клиенты пересекаются - один клиент запускается, а другой не заканчивает писать числа.
У меня проблема с первой трансляцией get_clients, потому что по неизвестной причине она иногда отправляется, а некоторые клиенты еще не созданы.Это особенно плохо, когда у меня 3 сервера и 2 клиента, и они могут даже не запуститься.Это странно для меня, потому что сначала создаются клиентские потоки, и мне интересно, есть ли какое-либо решение (кроме добавления sleep () между созданием клиентских потоков и потоков сервера, но я бы хотел этого избежать)
по какой-то причине программа не заканчивается, она просто останавливается в один момент, что может быть связано с предыдущими, но я пока не нашел решения для этого,
Есть ли у вас какие-либо идеи о том, что делать, чтобы со всеми клиентами обращались одинаково?Я имею в виду, что у меня есть 3 сервера и 100 клиентов, и я не хотел бы, чтобы возникала ситуация, когда несколько клиентов пишут все время, а есть группа, которая еще не имеет доступа к серверу
Буду благодарен за любую помощь:)