# Einige Worker-Threads mit NEWTHREADPOOL() teilen

> Starte eine feste Anzahl Worker, leihe dir mit pool.exec() einen aus, wenn Arbeit ansteht, gib ihn mit release() zurück und lass die anderen Aufgaben auf einen freien Worker warten.

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

`NEWTHREAD()` startet einen Worker. Wenn viele Anfragen dieselbe schwere Aufgabe brauchen, sind ein Worker pro Anfrage zu viele, und ein einzelner Worker lässt sie ohne Reihenfolge aufeinander warten. `NEWTHREADPOOL(name, count, [isfork])` startet `count` Worker aus `workers/<name>.js` (ein Thread; mit `isfork` auf `true` ein Kindprozess, wie bei `NEWFORK()`) und gibt sie einzeln aus.

- `pool.exec(function(worker, release) {})` wartet, bis ein Worker frei ist, und ruft deine Funktion mit ihm auf. Sende ihm die Arbeit mit `worker.postMessage(value)`, lies die Antwort mit `worker.once('message', fn)` und **rufe `release()` auf, wenn du fertig bist**: Der Worker geht zurück in den Pool, und die nächste wartende Aufgabe übernimmt ihn.
- Ohne Funktion gibt `pool.exec()` ein Promise zurück, das mit `worker` aufgelöst wird (und der Worker hat `worker.release()`), sodass es mit `await` funktioniert.
- Die Aufgaben werden in der Reihenfolge bedient, in der sie gefragt haben. Der Pool reiht die Nachrichten eines Workers nicht ein: Jeweils eine Aufgabe hat ihn.
- Der Pool wird auch in `F.workers[name]` gehalten. `pool.workers` ist die Liste der Worker.

Die Worker-Datei ist dieselbe wie für `NEWTHREAD()`: `NEWTHREAD()` darin gibt das Handle mit `worker.message` und `worker.postMessage()` zurück. Hier addiert jeder Worker die Zahlen und sagt, welcher Thread es getan hat.

```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 });
}
```
