Threads no Linux

Características e Recursos de Threads

Recursos Compartilhados

  • Instruções executáveis
  • Dados estáticos
  • Descritores de arquivos abertos
  • Diretório de trabalho atual
  • ID de usuário e grupo

Recursos Privados

  • Identificador de thread (TID)
  • Cnotador de programa e registradores
  • Pilha de execução
  • Código de erro (errno)
  • Prioridade e estado de execução

Operações Básicas

  • Criação e término de threads
  • Mecanismos de sincronização: semáforos e mutex

Criação de Threads

#include <pthread.h>
int pthread_criar(pthread_t *identificador,
                 const pthread_attr_t *atributos,
                 void *(*iniciar) (void *),
                 void *argumento);

Parâmetros:
identificador: Saída para ID da thread
atirbutos: Configurações ou NULL para padrão
iniciar: Função de entrada da thread
argumento: Dados passados para a thread

Exemplo Prático

#include <pthread.h>
#include <unistd.h>
#include <stdio.h>

void *tarefa(void *dado) {
    pthread_t id = *(pthread_t*)dado;
    printf("Processo: %d, Thread: %lu\n", getpid(), id);
    return NULL;
}

int principal() {
    pthread_t id;
    pthread_criar(&id, NULL, tarefa, &id);
    pthread_unir(id, NULL);
    return 0;
}

Gerenciamento de Threads

Encerramento

void pthread_sair(void *retorno);
int pthread_cancelar(pthread_t identificador);

Sincronização

int pthread_unir(pthread_t id, void **retorno);
int pthread_desvincular(pthread_t id);

Mutex e Variáveis de Condição

pthread_mutex_t bloqueio = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t condicao = PTHREAD_COND_INITIALIZER;

// Produtor
pthread_mutex_bloquear(&bloqueio);
// Produz recurso
pthread_cond_sinalizar(&condicao);
pthread_mutex_desbloquear(&bloqueio);

// Consumidor
pthread_mutex_bloquear(&bloqueio);
while (!recurso_disponivel) 
    pthread_cond_esperar(&condicao, &bloqueio);
// Consome recurso
pthread_mutex_desbloquear(&bloqueio);

Thread Pools

typedef struct {
    void (*executar)(void *);
    void *argumento;
    struct Tarefa *proxima;
} Tarefa;

typedef struct {
    pthread_t *threads;
    Tarefa *fila;
    pthread_mutex_t trava;
    pthread_cond_t nova_tarefa;
} PoolThreads;

void *trabalhador(void *pool) {
    PoolThreads *p = (PoolThreads*)pool;
    while (1) {
        pthread_mutex_bloquear(&p->trava);
        while (p->fila == NULL) 
            pthread_cond_esperar(&p->nova_tarefa, &p->trava);
        Tarefa *t = p->fila;
        p->fila = t->proxima;
        pthread_mutex_desbloquear(&p->trava);
        t->executar(t->argumento);
        free(t);
    }
}

Comunicação entre Processos

Pipes

int fd[2];
pipe(fd);
if (fork() == 0) {
    close(fd[0]);
    write(fd[1], dados, tamanho);
} else {
    close(fd[1]);
    read(fd[0], buffer, tamanho);
}

Filas de Mensagens

typedef struct {
    long tipo;
    char conteudo[128];
} Mensagem;

int id_fila = msgget(chave, IPC_CREAT | 0666);
msgsnd(id_fila, &msg, sizeof(msg.conteudo), 0);
msgrcv(id_fila, &msg, sizeof(msg.conteudo), 1, 0);

Sinais

void tratar_sinal(int s) {
    printf("Sinal %d recebido\n", s);
}

int main() {
    signal(SIGUSR1, tratar_sinal);
    raise(SIGUSR1);
    return 0;
}

Tags: pthread Sincronização Mutex IPC ThreadPool

Publicado em 6-5 03:25 por Thomas