---
title: "Como Lidar com Sinais (Signals) do Sistema em Zig"
url: "https://ziglang.com.br/receitas/como-lidar-com-sinais-signals-do-sistema-em-zig/"
markdown_url: "https://ziglang.com.br/receitas/como-lidar-com-sinais-signals-do-sistema-em-zig.MD"
description: "Aprenda a capturar e tratar sinais do sistema operacional em Zig. Exemplos com SIGINT, SIGTERM e shutdown gracioso de aplicações."
date: "2026-02-21"
author: "Zig Brasil"
---

# Como Lidar com Sinais (Signals) do Sistema em Zig

Aprenda a capturar e tratar sinais do sistema operacional em Zig. Exemplos com SIGINT, SIGTERM e shutdown gracioso de aplicações.


## Introdução

Sinais (signals) são notificações assíncronas enviadas pelo sistema operacional a um processo. Os mais comuns são SIGINT (Ctrl+C), SIGTERM (solicitação de término) e SIGHUP (terminal desconectado). Tratar sinais é essencial para servidores, processos de longa duração e aplicações que precisam realizar limpeza antes de encerrar.

Nesta receita, você aprenderá a capturar e tratar sinais em Zig.

## Pré-requisitos

- Zig instalado (versão 0.13+). Veja o [guia de instalação](/tutoriais/como-instalar-zig/)
- Conhecimento básico de Zig. Consulte a [introdução ao Zig](/tutoriais/introducao-ao-zig/)
- Sistema operacional POSIX (Linux/macOS)

## Capturar SIGINT (Ctrl+C)

```zig
const std = @import("std");
const posix = std.posix;

var running = std.atomic.Value(bool).init(true);

fn handler(sig: c_int) callconv(.C) void {
    _ = sig;
    std.debug.print("\nSinal recebido! Encerrando...\n", .{});
    running.store(false, .seq_cst);
}

pub fn main() !void {
    // Instalar handler para SIGINT
    const act = posix.Sigaction{
        .handler = .{ .handler = handler },
        .mask = posix.empty_sigset,
        .flags = 0,
    };

    try posix.sigaction(posix.SIG.INT, &act, null);

    std.debug.print("Programa rodando. Pressione Ctrl+C para encerrar.\n", .{});

    // Loop principal
    var contador: u32 = 0;
    while (running.load(.seq_cst)) {
        contador += 1;
        std.debug.print("\rTrabalhando... ciclo {d}", .{contador});
        std.time.sleep(std.time.ns_per_s);
    }

    std.debug.print("Encerramento limpo após {d} ciclos.\n", .{contador});
}
```

## Múltiplos Sinais

```zig
const std = @import("std");
const posix = std.posix;

var shutdown_requested = std.atomic.Value(bool).init(false);
var reload_requested = std.atomic.Value(bool).init(false);

fn sigintHandler(_: c_int) callconv(.C) void {
    shutdown_requested.store(true, .seq_cst);
}

fn sighupHandler(_: c_int) callconv(.C) void {
    reload_requested.store(true, .seq_cst);
}

pub fn main() !void {
    // Handler para SIGINT/SIGTERM -> encerrar
    const shutdown_act = posix.Sigaction{
        .handler = .{ .handler = sigintHandler },
        .mask = posix.empty_sigset,
        .flags = 0,
    };
    try posix.sigaction(posix.SIG.INT, &shutdown_act, null);
    try posix.sigaction(posix.SIG.TERM, &shutdown_act, null);

    // Handler para SIGHUP -> recarregar
    const reload_act = posix.Sigaction{
        .handler = .{ .handler = sighupHandler },
        .mask = posix.empty_sigset,
        .flags = 0,
    };
    try posix.sigaction(posix.SIG.HUP, &reload_act, null);

    std.debug.print("Servidor simulado rodando (PID: {d})\n", .{std.os.linux.getpid()});
    std.debug.print("  SIGINT/SIGTERM -> encerrar\n", .{});
    std.debug.print("  SIGHUP -> recarregar config\n", .{});

    while (!shutdown_requested.load(.seq_cst)) {
        if (reload_requested.load(.seq_cst)) {
            std.debug.print("Recarregando configuração...\n", .{});
            reload_requested.store(false, .seq_cst);
        }

        std.time.sleep(std.time.ns_per_ms * 500);
    }

    std.debug.print("Realizando shutdown gracioso...\n", .{});
    std.debug.print("Recursos liberados. Bye!\n", .{});
}
```

## Ignorar Sinais

```zig
const std = @import("std");
const posix = std.posix;

pub fn main() !void {
    // Ignorar SIGPIPE (comum em programas de rede)
    const ignore_act = posix.Sigaction{
        .handler = .{ .handler = posix.SIG.IGN },
        .mask = posix.empty_sigset,
        .flags = 0,
    };
    try posix.sigaction(posix.SIG.PIPE, &ignore_act, null);

    std.debug.print("SIGPIPE ignorado. Programa seguro para I/O de rede.\n", .{});
    std.debug.print("Operações de escrita em pipes fechados retornarão erro.\n", .{});
}
```

## Dicas e Boas Práticas

1. **Handlers devem ser simples**: Apenas defina flags atômicas no handler. Faça o trabalho pesado no loop principal.

2. **Use `std.atomic.Value(bool)`**: Para comunicação segura entre handler e código principal.

3. **Ignore SIGPIPE em servidores**: Previne que o programa termine ao escrever em conexões fechadas.

4. **Shutdown gracioso**: Ao receber SIGTERM, finalize conexões abertas, salve estado e libere recursos.

5. **Não use alocação em handlers**: Funções de sinal não devem chamar funções que alocam memória.

## Receitas Relacionadas

- [Criar e Gerenciar Threads](/receitas/zig-criar-thread/) - Threads em Zig
- [TCP Server](/receitas/zig-tcp-server/) - Servidor de rede
- [Time e Timestamps](/receitas/zig-tempo-timestamp/) - Tempo
- [Informações do Sistema](/receitas/zig-informacoes-sistema/) - Info do OS

## Tutoriais Relacionados

- [Concorrência em Zig](/tutoriais/concorrencia-em-zig/)
- [Introdução ao Zig](/tutoriais/introducao-ao-zig/)
