Neste artigo, usaremos chamadas reais do sistema para fazer trabalhos reais em nosso programa C. Primeiro, analisaremos se você precisar usar uma chamada do sistema, depois forneça um exemplo usando a chamada sendfile () que pode melhorar drasticamente o desempenho da cópia do arquivo. Por fim, examinaremos alguns pontos a serem lembrados ao usar chamadas do sistema Linux.
Embora seja inevitável, você usará uma chamada do sistema em algum momento da sua carreira de desenvolvimento C, a menos que você esteja segmentando alto desempenho ou uma funcionalidade de tipo específico, a biblioteca GLIBC e outras bibliotecas básicas incluídas nas principais distribuições do Linux cuidarão da maioria da maioria dos suas necessidades.
A Biblioteca Padrão Glibc fornece uma estrutura de plataforma cruzada e bem testada para executar funções que, de outra forma, exigiriam chamadas de sistema específicas do sistema. Por exemplo, você pode ler um arquivo com fscanf (), fread (), getc (), etc., ou você pode usar a chamada do sistema read () linux. As funções glibc fornecem mais recursos (i.e. melhor manuseio de erros, IO formatado, etc.) e funcionará em qualquer sistema de suportes do GLIBC do sistema.
Por outro lado, há momentos em que o desempenho intransigente e a execução exata são críticos. O invólucro que Fread () fornece vai adicionar sobrecarga e, embora menor, não é totalmente transparente. Além disso, você pode não querer ou precisar dos recursos extras que o invólucro fornece. Nesse caso, você é melhor servido com uma chamada de sistema.
Você também pode usar chamadas do sistema para executar funções ainda não suportadas pelo Glibc. Se sua cópia do Glibc estiver atualizada, isso dificilmente será um problema, mas o desenvolvimento de distribuições mais antigas com kernels mais recentes poderá exigir essa técnica.
Agora que você leu as isenções de responsabilidade, avisos e desvios em potencial, agora vamos cavar alguns exemplos práticos.
Em que CPU estamos?
Uma pergunta que a maioria dos programas provavelmente não pensa em fazer, mas um válido, no entanto. Este é um exemplo de chamada de sistema que não pode ser duplicada com glibc e não é coberta com um invólucro glibc. Neste código, chamaremos a chamada getCPU () diretamente através da função syscall (). A função syscall funciona da seguinte maneira:
syscall (sys_call, arg1, arg2,…);O primeiro argumento, sys_call, é uma definição que representa o número da chamada do sistema. Quando você inclui sys/syscall.h estes estão incluídos. A primeira parte é sys_ e a segunda parte é o nome da chamada do sistema.
Argumentos para a chamada entram no arg1, arg2 acima. Algumas chamadas exigem mais argumentos e continuarão em ordem na página do homem. Lembre -se de que a maioria dos argumentos, especialmente para devoluções, exigirá que os ponteiros cheguem a matrizes ou a memória alocada pela função malloc.
Exemplo 1.c
#incluirPara obter resultados mais interessantes, você pode girar tópicos através da biblioteca Pthreads e depois chamar essa função para ver em qual processador seu tópico está executando.
Sendfile: desempenho superior
O Sendfile fornece um excelente exemplo de aprimoramento do desempenho através de chamadas do sistema. O função sendfile () copia dados de um descritor de arquivo para outro. Em vez de usar as funções múltiplas Fread () e Fwrite (), o Sendfile executa a transferência no espaço do kernel, reduzindo a sobrecarga e assim aumentando o desempenho.
Neste exemplo, vamos copiar 64 MB de dados de um arquivo para outro. Em um teste, usaremos os métodos padrão de leitura/gravação na biblioteca padrão. No outro, usaremos as chamadas do sistema e a chamada sendfile () para explodir esses dados de um local para outro.
Test1.C (glibc)
#incluirTest2.C (chamadas do sistema)
#incluirTestes de compilação e corrida 1 e 2
Para construir esses exemplos, você precisará das ferramentas de desenvolvimento instaladas em sua distribuição. No Debian e Ubuntu, você pode instalar isso com:
APT Instale os essenciais de construção
Em seguida, compilar com:
GCC Test1.c -o test1 && gcc test2.C -O Test2
Para executar os dois e testar o desempenho, execute:
tempo ./test1 && time ./test2
Você deve obter resultados como este:
Teste de E/S com funções tradicionais do glibc.
Alocando o buffer de 64 MB: feitoComo você pode ver, o código que usa as chamadas do sistema funciona muito mais rápido que o equivalente do Glibc.
Coisas para lembrar
As chamadas do sistema podem aumentar o desempenho e fornecer funcionalidades adicionais, mas não estão sem suas desvantagens. Você terá que pesar as chamadas do sistema de benefícios fornecem contra a falta de portabilidade da plataforma e às vezes a funcionalidade reduzida em comparação com as funções da biblioteca.
Ao usar algumas chamadas do sistema, você deve tomar cuidado para usar os recursos devolvidos das chamadas do sistema, em vez de funções da biblioteca. Por exemplo, a estrutura de arquivos usada para as funções FOPEN (), Fread (), Fwrite () e Fclose () não são as mesmas que o número do descritor de arquivo da chamada Open () (retornada como um número inteiro). Misturar isso pode levar a problemas.
Em geral, as chamadas do sistema Linux têm menos faixas de pára -choques do que as funções do GLIBC. Embora seja verdade que as chamadas do sistema têm algum tratamento de erros e relatórios, você obterá uma funcionalidade mais detalhada de uma função glibc.
E finalmente, uma palavra sobre segurança. Chamadas de sistema interface diretamente com o kernel. O kernel Linux tem proteções extensas contra travessuras da terra do usuário, mas existem bugs não descobertos. Não confie que uma chamada do sistema validará sua entrada ou isolá -lo de problemas de segurança. É aconselhável garantir que os dados que você entregam a uma chamada do sistema estão higienizados. Naturalmente, este é um bom conselho para qualquer chamada de API, mas você não pode ter cuidado ao trabalhar com o kernel.
Espero que você tenha gostado deste mergulho mais profundo na terra das chamadas do sistema Linux. Para uma lista completa de chamadas do sistema Linux, consulte nossa lista mestre.