# Green threads

Quando falamos de **threads**, geralmente estamos nos referindo a *threads do sistema operacional*, ou **kernel threads**. Algumas implementações de linguagens de programação, como o *GCC em C*, permitem utilizar kernel threads, que no caso do C é através da função `pthread_create` .

Mas como vimos no tópico sobre os desafios com o uso de kernel threads, a gestão de milhares de threads pode aumentar consideravelmente a latência do sistema.

Como alternativa, algumas implementações optam por usar abstrações similar a threads dentro do próprio runtime, pelo que precisam desenvolver o próprio escalonador de threads.&#x20;

A essas threads que vivem dentro do runtime, ou como costumamos dizer, *a nível do usuário*, damos o nome de **green threads**.

Mas antes de falarmos das green threads, vamos relembrar o funcionamento de uma kernel thread.

## Funcionamento de uma kernel thread

Como já aprendemos nos tópicos anteriores, em C conseguimos criar threads do sistema operacional, ou kernel threads. Basicamente, uma kernel thread tem uma pilha onde guarda o estado de execução entre outros metadados:

<figure><img src="/files/DaoxIFp224I8OYOMPhWt" alt="" width="563"><figcaption></figcaption></figure>

Em C, a chamada da função `pthread_create` basicamente cria uma kernel thread, então a gestão de escalonamento e troca de contexto fica completamente a cargo do kernel (SO), e não do GCC:

<figure><img src="/files/Mtv69zCfLtmU3hp16kTV" alt="" width="563"><figcaption></figcaption></figure>

## Como funciona uma green thread

Uma green thread geralmente tem uma estrutura similar a uma kernel thread, contendo sua própria pilha de memória mas compartilhando a memória principal do processo.&#x20;

Mas uma green thread tem a vantagem de não levar com a latência da criação de kernel threads, ou seja, dependendo da *implementação de green threads no runtime*, podemos criar milhares, senão **milhões de green threads** mantendo baixa latência.

A nível de implementação, em determinado momento vamos precisar "associar" as green threads às kernel threads, afinal:

> Todo programa roda em uma thread principal, ou seja, para o escalonador do sistema operacional é *tudo thread*, ou melhor ainda, **é tudo task**

O desafio é então *multiplexar* um número arbitrário de green threads para kernel threads, e isto pode ser feito de várias formas. Vamos a seguir detalhar alguns tipos comuns de implementação de green threads.

### 1. Uma kernel thread, múltiplas green threads

Neste tipo de implementação, temos apenas uma thread principal do programa que é mapeada diretamente para uma kernel thread. E dentro desta thread, criamos múltiplas green threads:

<figure><img src="/files/VItrrvCskqNkwGpCOJio" alt="" width="563"><figcaption></figcaption></figure>

A vantagem desta abordagem é que temos **menos latência** comparando com o uso indiscriminado de kernel threads, mas por outro lado, a desvantagem é que **não temos um paralelismo real** mesmo em CPU multi-core, pois o sistema operacional não sabe que se trata de uma green thread, então no fim das contas é apenas **uma thread** sendo utilizada na CPU.

### 2. Multiplexação de N green threads para M kernel threads

Esta abordagem é muito comum no runtime Go, e é basicamente a capacidade de criar uma kernel thread para um conjunto específico de green threads:

<figure><img src="/files/n3gdAYDvuxGSBPbgBheP" alt="" width="563"><figcaption></figcaption></figure>

A vantagem nisso é que podemos utilizar mais paralelismo, uma vez que cada kernel thread pode utilizar um núcleo de CPU. Se o runtime for espertinho o suficiente, temos uma situação muito interessante para lidar com concorrência e paralelismo.

> Alô Gophers, o momento de vocês está chegando :P

### 3. Múltiplos escalonadores

Outra abordagem muito interessante, e que é utilizada na implementação do Erlang/Elixir (BEAM), é que poderíamos multiplexar kernel threads pra cada escalonador. Assim, cada escalonador iria cuidar de um número X de *green threads* mantendo o paralelismo real.

<figure><img src="/files/Rpfb0udECxuROvEwumaG" alt=""><figcaption></figcaption></figure>

Mas a ideia por enquanto não é falar de Go nem Erlang, pois estamos ainda no C. Chegou o momento de entender como podemos trabalhar com green threads em C.

## Green threads em C

Infelizmente, a implementação padrão do GCC não traz suporte a green threads. O que até faz sentido, imagina o C trazer isso? Seria overkill, sendo uma linguagem bastante genérica, de propósito geral e muito perto do sistema operacional.

Mas há algumas bibliotecas externas que trazem este conceito, onde podemos ter "green threads" em C contando com uma estrutura de escalonamento das threads:

* [libdill.org](https://libdill.org/): green threads (chamadas na lib de **corrotinas**), com comunicação baseada em canais e escalonamento cooperativo
* [libmill.org](https://libmill.org/): similar à libdill, mas implementada de forma mais robusta e escalável, com multiplexing de kernel threads semelhante ao que temos em Go
* ...entre outras, como libtask, libcoro, GNU pth etc


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://concorrencia101.leandronsp.com/parte-ii-concorrencia-em-diferentes-linguagens/concorrencia-em-c/green-threads.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
