Puoi farlo?
Fornire un'interfaccia software è come offrire un servizio a un cliente. Un cliente può scegliere qualsiasi servizio offerto da chiunque. Ad esempio, se la libreria A fornisce un task scheduler e la libreria B fornisce un modo semplice per creare nuovi thread, un cliente può scegliere di utilizzare entrambi.
Perché il cliente vuole farlo? Posso convincere il cliente a non farlo?
I modi migliori per convincere il cliente a non combinarlo con un altro servizio sono:
- Offrendo lo stesso servizio (equivalente o anche migliore),
- Spiega ai tuoi clienti perché è meglio non combinarlo con un altro servizio e spero che capiscano
Che cosa succede se esiste un problema tecnico legittimo che non lo rende una buona idea?
Spiega che la preoccupazione tecnica per i clienti è comprensibile.
Ad esempio, una delle maggiori minacce all'implementazione del pool di thread a dimensione fissa è che una funzione worker può richiamare un Sleep
che lega il thread per qualche tempo o un Lock
/ Acquire
(bloccando wait) che può essere sbloccato solo da un altro thread di lavoro. Si consideri un semplice scenario che tutti gli 8 thread di un pool di 8 thread fisso decidono di bloccare. Poiché non ci sono altri thread in grado di eseguire il codice per sbloccarlo, questi 8 thread sono in un inceppamento per sempre.
Pertanto, le implementazioni del pool di thread fisso devono spiegare all'utente che è pericoloso utilizzare qualsiasi cosa possa bloccare all'interno delle funzioni di lavoro. In particolare, è ancora più pericoloso se il codice worker tenta di acquisire qualsiasi lock / monitor che può essere rilasciato solo da un altro thread worker.
Infine, introducete all'utente diverse alternative ai blocchi che si rivelano utili nel carico di lavoro computazionale.
- Ad esempio, i risultati di ciascun thread di lavoro possono essere temporaneamente memorizzati o aggiunti a un elenco o dizionario simultanei e combinati in un secondo momento.
- Allo stesso modo, è possibile allocare una matrice abbastanza grande in modo che ogni thread di lavoro possa scrivere risultati su parti non sovrapposte della matrice senza calpestare le rispettive aree di output.
- I dati immutabili condivisi non necessitano della protezione del lucchetto.
- E così via. (Esistono white paper da alcune librerie di concorrenza che insegnano le migliori pratiche come queste.)
Che cosa succede se sono davvero interessato a bloccare il codice dell'utente cercando di generare nuovi thread?
Questo rientra nei privilegi limitanti per il codice in esecuzione. I privilegi limitanti richiedono il supporto al runtime dall'ambiente di esecuzione. In altre parole, se l'ambiente di esecuzione non implementa il rilascio dei privilegi durante l'esecuzione del codice, non è possibile implementare questa funzionalità da soli. Nella migliore delle ipotesi puoi mettere della documentazione per persuadere i tuoi utenti perché è una cattiva idea farlo.
In generale, se vuoi togliere la libertà dell'utente di usare un altro servizio, dovrai scoprire che il fornitore di altri servizi (ad es. l'ambiente runtime o il sistema operativo, o un altro software), e poi chiederlo fornitore di bloccare l'accesso (vedi: controllo degli accessi), o in qualche modo interferire con quel servizio (vedere: rifiuto del servizio).
Questa vecchia domanda su StackOverflow potrebbe essere utile. Però non esitare a cercare risposte nuove e più accurate.
Alcuni ambienti di esecuzione forniscono controlli di accesso molto elaborati:
(Non ho familiarità con queste cose, quindi non posso spiegare ulteriormente.)
Infine, puoi eseguire il codice utente all'interno del tuo ambiente, che è diverso da quello su cui il tuo codice viene eseguito. Questo è chiamato Sandbox. Il codice dell'utente è come un prigioniero che vive all'interno di un dungeon creato da te.