/** * ============================================================================ * PHM Tech & PHM Open Source · Prof. Paulo Henrique Maciel * Eixo 09: Comunicação Interprocessos (IPC: Pipes Unidirecionais POSIX) * ============================================================================ * * OBJETIVO PEDAGÓGICO: * Demonstrar como processos concorrentes em sistemas operacionais UNIX/Linux * trocam dados de forma segura utilizando o mecanismo de IPC (Inter-Process * Communication) via Pipes anônimos (canais unidirecionais em memória de kernel). * * CONCEITOS-CHAVE: * 1. IPC (Inter-Process Communication): Troca de dados entre processos isolados. * 2. pipe(fd[2]): Cria um canal com descritor de leitura fd[0] e escrita fd[1]. * 3. fork(): Criação de processo Filho que herda a tabela de arquivos do Pai. * 4. Fechamento de pontas não utilizadas (close(fd[0]) ou close(fd[1])). * 5. Bloqueio síncrono de I/O em read() até que dados estejam disponíveis. * * COMO COMPILAR E EXECUTAR: * Linux / WSL / POSIX: gcc 09_comunicacao_interprocessos_pipes.c -o so_ipc && ./so_ipc * ============================================================================ */ #include #include #include #if defined(_WIN32) && !defined(__CYGWIN__) // Mensagem didática para ambiente Windows nativo int main(void) { printf("===============================================================\n"); printf(" EIXO 09: COMUNICAÇÃO INTERPROCESSOS (IPC POSIX PIPES)\n"); printf(" Prof. Paulo Henrique Maciel · PHM Tech Open Source\n"); printf("===============================================================\n\n"); printf("[AVISO ACADÊMICO]: O mecanismo 'pipe()' e 'fork()' utiliza chamadas de sistema\n"); printf("nativas do kernel POSIX (Linux/UNIX/macOS/WSL/MSYS2).\n\n"); printf("Demonstração do Fluxo Lógico:\n"); printf(" 1. Processo Pai cria pipe: [Escrita fd[1]] ====> [Leitura fd[0]]\n"); printf(" 2. Processo Pai gera fork() e envia mensagem criptografada pelo canal.\n"); printf(" 3. Processo Filho lê os dados do pipe, processa e exibe no console.\n\n"); printf("Para executar em tempo real no Windows, utilize WSL, MSYS2 ou o compilador OnlineGDB.\n"); return 0; } #else #include #include #include #define BUFFER_SIZE 256 int main(void) { printf("===============================================================\n"); printf(" EIXO 09: COMUNICAÇÃO INTERPROCESSOS (IPC POSIX PIPES)\n"); printf(" Prof. Paulo Henrique Maciel · PHM Tech Open Source\n"); printf("===============================================================\n\n"); int fd[2]; // fd[0] = Leitura (Read End) | fd[1] = Escrita (Write End) char mensagem_envio[] = "MENSAGEM DO PROCESSO PAI: Alocação de recursos autorizada pelo Kernel!"; char buffer_recebido[BUFFER_SIZE]; // [1] Criação do canal IPC (Pipe) if (pipe(fd) == -1) { perror("Falha ao criar o Pipe IPC"); return EXIT_FAILURE; } printf("[KERNEL] Pipe criado com sucesso (Descritores: Leitura=%d, Escrita=%d)\n", fd[0], fd[1]); // [2] Criação do processo filho pid_t pid = fork(); if (pid < 0) { perror("Falha ao executar fork()"); return EXIT_FAILURE; } if (pid > 0) { // ==================================================================== // PROCESSO PAI (Escritor / Producer) // ==================================================================== printf("[PAI (PID: %d)] Fechando descritor de leitura fd[0]...\n", getpid()); close(fd[0]); // O Pai não vai ler, apenas escrever printf("[PAI (PID: %d)] Enviando dados pelo pipe: \"%s\"\n", getpid(), mensagem_envio); write(fd[1], mensagem_envio, strlen(mensagem_envio) + 1); printf("[PAI (PID: %d)] Dados gravados. Fechando canal de escrita fd[1]...\n", getpid()); close(fd[1]); // Aguarda a finalização do processo filho wait(NULL); printf("\n[PAI (PID: %d)] Processo filho finalizou. IPC concluído com êxito!\n", getpid()); } else { // ==================================================================== // PROCESSO FILHO (Leitor / Consumer) // ==================================================================== printf("[FILHO (PID: %d)] Fechando descritor de escrita fd[1]...\n", getpid()); close(fd[1]); // O Filho não vai escrever, apenas ler printf("[FILHO (PID: %d)] Aguardando dados no pipe (bloqueante)...\n", getpid()); ssize_t bytes_lidos = read(fd[0], buffer_recebido, sizeof(buffer_recebido)); if (bytes_lidos > 0) { printf("[FILHO (PID: %d)] SUCESSO! Dados recebidos do Pai (%zd bytes): \"%s\"\n", getpid(), bytes_lidos, buffer_recebido); } close(fd[0]); // Fecha o descritor de leitura exit(EXIT_SUCCESS); } return EXIT_SUCCESS; } #endif