# Споделете няколко работни нишки с NEWTHREADPOOL()

> Стартирайте фиксиран брой workers, вземете един с pool.exec(), когато има работа, върнете го с release() и оставете другите задачи да чакат свободен worker.

Framework: total5
Product: Total.js 5 (total5@0.0.19)
Language: bg
Content-SHA256: 4ccf2467593fd1d7bd8d553fb82ba61acdae7fcffc7b4d200844119bd0ac05c6
Snapshot: c0700e321579725c5cf4f5ace1ad7d2866d1b4f93c24a63c0b41b6b7998e976c
Sources: total5-installed@total5@0.0.19
Review: not-recorded

`NEWTHREAD()` стартира един worker. Когато много заявки се нуждаят от една и съща тежка работа, по един worker на заявка са твърде много, а един-единствен worker ги кара да се чакат без никакъв ред. `NEWTHREADPOOL(name, count, [isfork])` стартира `count` workers от `workers/<name>.js` (нишка; с `isfork` на `true`, дъщерен процес, като `NEWFORK()`) и ги раздава един по един.

- `pool.exec(function(worker, release) {})` чака, докато има свободен worker, и извиква вашата функция с него. Изпратете му работата с `worker.postMessage(value)`, прочетете отговора с `worker.once('message', fn)` и **извикайте `release()`, когато приключите**: workerът се връща в пула и следващата чакаща задача го взема.
- Без функция `pool.exec()` връща promise, който се изпълнява с `worker` (а workerът има `worker.release()`), така че работи с `await`.
- Задачите се обслужват в реда, в който са поискали. Пулът не подрежда в опашка съобщенията на worker: по една задача в даден момент го има.
- Пулът се пази и в `F.workers[name]`. `pool.workers` е списъкът на workers.

Файлът на worker е същият като за `NEWTHREAD()`: `NEWTHREAD()` в него връща манипулатора с `worker.message` и `worker.postMessage()`. Тук всеки worker сумира числата и казва коя нишка го е направила.

```js workers/total.js
require('total5');

const worker = NEWTHREAD();

worker.message = function(message) {
	let total = 0;
	for (let i = 1; i <= message.to; i++)
		total += i;
	worker.postMessage({ to: message.to, total: total, thread: require('worker_threads').threadId });
};
```

```js controllers/total.js
exports.install = function() {
	ROUTE('GET /total/{to}/', total);
	ROUTE('GET /await/{to}/', total_await);
	ROUTE('GET /workers/', workers);
};

const pool = NEWTHREADPOOL('total', 2);

function total($) {
	pool.exec(function(worker, release) {
		worker.once('message', function(response) {
			release();
			$.json(response);
		});
		worker.postMessage({ to: +$.params.to });
	});
}

async function total_await($) {
	const worker = await pool.exec();
	worker.once('message', function(response) {
		worker.release();
		$.json(response);
	});
	worker.postMessage({ to: +$.params.to });
}

function workers($) {
	$.json({ workers: pool.workers.length, registered: F.workers.total === pool });
}
```
