Multithreading em C
O que é um tópico?
Um thread é um único fluxo de sequência dentro de um processo. Como os threads têm algumas das propriedades dos processos, às vezes são chamados de processos leves .
Quais são as diferenças entre processo e thread?
Threads não são independentes uns dos outros como processos, como resultado, os threads compartilham com outros threads sua seção de código, seção de dados e recursos do sistema operacional, como arquivos abertos e sinais. Mas, como o processo, uma thread tem seu próprio contador de programa (PC), um conjunto de registros e um espaço de pilha.
Por que multithreading?
Threads são uma forma popular de melhorar a aplicação por meio do paralelismo. Por exemplo, em um navegador, várias guias podem ser threads diferentes. O MS Word usa vários threads, um thread para formatar o texto, outro thread para processar entradas, etc.
Threads operam mais rápido do que processos devido aos seguintes motivos:
1) A criação de thread é muito mais rápida.
2) A troca de contexto entre threads é muito mais rápida.
3) Os threads podem ser encerrados facilmente
4) A comunicação entre os threads é mais rápida.
Veja http://www.personal.kent.edu/~rmuhamma/OpSystems/Myos/threads.htm para mais detalhes.
Podemos escrever programas multithreading em C?
Ao contrário do Java, o multithreading não é compatível com o padrão de linguagem. POSIX Threads (ou Pthreads) é um padrão POSIX para threads. A implementação de pthread está disponível com o compilador gcc.
Um programa C simples para demonstrar o uso das funções básicas de pthread
Observe que o programa abaixo pode ser compilado apenas com compiladores C com a biblioteca pthread.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> //Header file for sleep(). man 3 sleep for details.
#include <pthread.h>
// A normal C function that is executed as a thread
// when its name is specified in pthread_create()
void *myThreadFun(void *vargp)
{
sleep(1);
printf("Printing GeeksQuiz from Thread \n");
return NULL;
}
int main()
{
pthread_t thread_id;
printf("Before Thread\n");
pthread_create(&thread_id, NULL, myThreadFun, NULL);
pthread_join(thread_id, NULL);
printf("After Thread\n");
exit(0);
}
Em main(), declaramos uma variável chamada thread_id, que é do tipo pthread_t, que é um inteiro usado para identificar a thread no sistema. Depois de declarar thread_id, chamamos a função pthread_create() para criar uma thread.
pthread_create() recebe 4 argumentos.
O primeiro argumento é um ponteiro para thread_id que é definido por esta função.
O segundo argumento especifica atributos. Se o valor for NULL, os atributos padrão devem ser usados.
O terceiro argumento é o nome da função a ser executada para o thread a ser criado.
O quarto argumento é usado para passar argumentos para a função, myThreadFun.
A função pthread_join() para threads é equivalente a wait() para processos. Uma chamada para pthread_join bloqueia o encadeamento de chamada até que o encadeamento com o identificador igual ao primeiro argumento termine.
Como compilar o programa acima?
Para compilar um programa multithread usando gcc, precisamos vinculá-lo à biblioteca pthreads. A seguir está o comando usado para compilar o programa.
gfg@ubuntu:~/$ gcc multithread.c -lpthread gfg@ubuntu:~/$ ./a.out Before Thread Printing GeeksQuiz from Thread After Thread gfg@ubuntu:~/$
Programa AC para mostrar vários threads com variáveis globais e estáticas
Como mencionado acima, todos os threads compartilham segmento de dados. Variáveis globais e estáticas são armazenadas no segmento de dados. Portanto, eles são compartilhados por todos os threads. O programa de exemplo a seguir demonstra o mesmo.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
// Let us create a global variable to change it in threads
int g = 0;
// The function to be executed by all threads
void *myThreadFun(void *vargp)
{
// Store the value argument passed to this thread
int *myid = (int *)vargp;
// Let us create a static variable to observe its changes
static int s = 0;
// Change static and global variables
++s; ++g;
// Print the argument, static and global variables
printf("Thread ID: %d, Static: %d, Global: %d\n", *myid, ++s, ++g);
}
int main()
{
int i;
pthread_t tid;
// Let us create three threads
for (i = 0; i < 3; i++)
pthread_create(&tid, NULL, myThreadFun, (void *)&tid);
pthread_exit(NULL);
return 0;
}
gfg@ubuntu:~/$ gcc multithread.c -lpthread gfg@ubuntu:~/$ ./a.out Thread ID: 3, Static: 2, Global: 2 Thread ID: 3, Static: 4, Global: 4 Thread ID: 3, Static: 6, Global: 6 gfg@ubuntu:~/$
Observe que acima é um exemplo simples para mostrar como os threads funcionam. Acessar uma variável global em um thread geralmente é uma má ideia. E se o thread 2 tiver prioridade sobre o thread 1 e o thread 1 precisar alterar a variável. Na prática, se for necessário acessar a variável global por vários threads, eles devem ser acessados usando um mutex.
Referências:
http://www.csc.villanova.edu/~mdamian/threads/posixthreads.html
Sistemas de computador: um programador
Este artigo é uma contribuição de Rahul Jain . Escreva comentários se encontrar algo incorreto ou se quiser compartilhar mais informações sobre o tópico discutido acima
As postagens do blog Acervo Lima te ajudaram? Nos ajude a manter o blog no ar!
Faça uma doação para manter o blog funcionando.
70% das doações são no valor de R$ 5,00...
Diógenes Lima da Silva