#include #include #include #include #include #include #include #define ACCOUNT_SIZE 16 #define MAX_NAME_LEN 10 #define MAX_BALANCE_LEN 5 #define FILENAME "../Data/accounts.db" // Fonction pour lire un compte dans le fichier void read_account(int fd, int index, char *name, int *balance) { char buffer[ACCOUNT_SIZE]; lseek(fd, index * ACCOUNT_SIZE, SEEK_SET); read(fd, buffer, ACCOUNT_SIZE); sscanf(buffer, "%10s %d", name, balance); } // Fonction pour écrire un compte dans le fichier void write_account(int fd, int index, const char *name, int balance) { char buffer[ACCOUNT_SIZE]; // Formater la chaîne avec un nom de 10 caractères et un solde de 5 caractères, espace rempli si nécessaire snprintf(buffer, ACCOUNT_SIZE, "%-10s%5d", name, balance); // S'assurer que le buffer est exactement de taille ACCOUNT_SIZE // Ajouter des espaces si nécessaire pour remplir la ligne for (int i = strlen(buffer); i < ACCOUNT_SIZE - 1; i++) { buffer[i] = ' '; } buffer[ACCOUNT_SIZE - 1] = '\n'; // Assurez-vous que la ligne est terminée correctement // Positionner et écrire dans le fichier lseek(fd, index * ACCOUNT_SIZE, SEEK_SET); write(fd, buffer, ACCOUNT_SIZE); } // Fonction pour effectuer une transaction void perform_transaction(int fd, int account_count) { int from_idx = rand() % account_count; int to_idx = rand() % account_count; while (from_idx == to_idx) { to_idx = rand() % account_count; } char from_name[MAX_NAME_LEN], to_name[MAX_NAME_LEN]; int from_balance, to_balance; // Lire les comptes source et destination read_account(fd, from_idx, from_name, &from_balance); read_account(fd, to_idx, to_name, &to_balance); // Calculer un montant aléatoire à transférer (max 20% du solde source) int max_transfer = from_balance / 5; if (max_transfer > 0) { int transfer_amount = rand() % max_transfer; // Effectuer la transaction from_balance -= transfer_amount; to_balance += transfer_amount; // Écrire les nouveaux soldes dans le fichier write_account(fd, from_idx, from_name, from_balance); write_account(fd, to_idx, to_name, to_balance); printf("Transaction : %s -> %s : %d€\n", from_name, to_name, transfer_amount); } else { printf("Transaction annulée : Fonds insufisants %s\n", from_name); } } // Fonction pour un processus de transactions void process_transactions(int transactions, int account_count) { int fd = open(FILENAME, O_RDWR); if (fd < 0) { perror("Erreur : Impossible d'ouvrir le fichier"); exit(1); } for (int i = 0; i < transactions; i++) { perform_transaction(fd, account_count); usleep(rand() % 100000); // Temporisation aléatoire } close(fd); } int calculate_total_balance() { int fd = open(FILENAME, O_RDONLY); if (fd < 0) { perror("Erreur : Impossible d'ouvrir le fichier"); return -1; } off_t file_size = lseek(fd, 0, SEEK_END); int account_count = file_size / ACCOUNT_SIZE; int total_balance = 0; char name[MAX_NAME_LEN]; int balance; for (int i = 0; i < account_count; i++) { read_account(fd, i, name, &balance); total_balance += balance; } close(fd); return total_balance; } int main(int argc, char *argv[]) { if (argc != 3) { fprintf(stderr, "Usage: %s \n", argv[0]); return 1; } int num_processes = atoi(argv[1]); int transactions_per_process = atoi(argv[2]); srand(time(NULL)); // Calcul du solde total initial int initial_balance = calculate_total_balance(); if (initial_balance < 0) { return 1; // Erreur lors de l'ouverture du fichier } printf("Solde total initial : %d€\n", initial_balance); // Ouvrir le fichier pour déterminer le nombre de comptes int fd = open(FILENAME, O_RDONLY); if (fd < 0) { perror("Erreur : Impossible d'ouvrir le fichier"); return 1; } off_t file_size = lseek(fd, 0, SEEK_END); close(fd); int account_count = file_size / ACCOUNT_SIZE; printf("Nombre de comptes : %d\n", account_count); // Créer les processus enfants for (int i = 0; i < num_processes; i++) { if (fork() == 0) { process_transactions(transactions_per_process, account_count); exit(0); } } // Attendre les processus enfants for (int i = 0; i < num_processes; i++) { wait(NULL); } // Calcul du solde total final int final_balance = calculate_total_balance(); if (final_balance < 0) { return 1; // Erreur lors de l'ouverture du fichier } printf("Solde total final : %d€\n", final_balance); if (initial_balance != final_balance) { printf("Le solde final est différent du solde initial...\n"); } printf("Tout les processus sont terminés !\n"); return 0; }