1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

ThreadPool: Add support for a user specified thread name

This commit is contained in:
Anthony Nicholls 2023-06-19 12:24:45 +00:00
parent 21aca5ba3e
commit b3da4ae946
9 changed files with 96 additions and 30 deletions

View file

@ -317,7 +317,8 @@ private:
}
//==============================================================================
ThreadPool pool { 3 };
ThreadPool pool { ThreadPoolOptions{}.withThreadName ("Demo thread pool")
.withNumberOfThreads (3) };
TextButton controlButton { "Thread type" };
bool isUsingPool = false;

View file

@ -50,7 +50,7 @@
FileSearchPath paths;
static constexpr auto numJobs = 5;
ThreadPool pool { numJobs };
ThreadPool pool { ThreadPoolOptions{}.withNumberOfThreads (numJobs) };
void startScan()
{

View file

@ -363,7 +363,7 @@ private:
}
//==============================================================================
ThreadPool jobPool { 1 };
ThreadPool jobPool { ThreadPoolOptions{}.withNumberOfThreads (1) };
//==============================================================================
JUCE_DECLARE_WEAK_REFERENCEABLE (LicenseQueryThread)

View file

@ -553,7 +553,7 @@ private:
if (numThreads > 0)
{
pool.reset (new ThreadPool (numThreads));
pool.reset (new ThreadPool (ThreadPoolOptions{}.withNumberOfThreads (numThreads)));
for (int i = numThreads; --i >= 0;)
pool->addJob (new ScanJob (*this), true);

View file

@ -80,7 +80,7 @@ using DisableIfSameOrDerived = std::enable_if_t<! std::is_base_of_v<A, std::remo
/** Copies an object, sets one of the copy's members to the specified value, and then returns the copy. */
template <typename Object, typename OtherObject, typename Member, typename Other>
Object withMember (Object copy, Member OtherObject::* member, Other&& value)
[[nodiscard]] Object withMember (Object copy, Member OtherObject::* member, Other&& value)
{
copy.*member = std::forward<Other> (value);
return copy;

View file

@ -42,6 +42,9 @@ namespace juce
class JUCE_API Thread
{
public:
//==============================================================================
static constexpr size_t osDefaultStackSize { 0 };
//==============================================================================
/** The different runtime priorities of non-realtime threads.
@ -95,7 +98,7 @@ public:
is zero then the default stack size of the OS will
be used.
*/
explicit Thread (const String& threadName, size_t threadStackSize = 0);
explicit Thread (const String& threadName, size_t threadStackSize = osDefaultStackSize);
/** Destructor.

View file

@ -25,8 +25,9 @@ namespace juce
struct ThreadPool::ThreadPoolThread : public Thread
{
ThreadPoolThread (ThreadPool& p, size_t stackSize)
: Thread ("Pool", stackSize), pool (p)
ThreadPoolThread (ThreadPool& p, const ThreadPoolOptions& options)
: Thread { options.threadName, options.threadStackSizeBytes },
pool { p }
{
}
@ -93,18 +94,24 @@ ThreadPoolJob* ThreadPoolJob::getCurrentThreadPoolJob()
}
//==============================================================================
ThreadPool::ThreadPool (int numThreads, size_t threadStackSize, Thread::Priority priority)
ThreadPool::ThreadPool (const ThreadPoolOptions& options)
{
jassert (numThreads > 0); // not much point having a pool without any threads!
// not much point having a pool without any threads!
jassert (options.numberOfThreads > 0);
for (int i = jmax (1, numThreads); --i >= 0;)
threads.add (new ThreadPoolThread (*this, threadStackSize));
for (int i = jmax (1, options.numberOfThreads); --i >= 0;)
threads.add (new ThreadPoolThread (*this, options));
for (auto* t : threads)
t->startThread (priority);
t->startThread (options.desiredThreadPriority);
}
ThreadPool::ThreadPool() : ThreadPool (SystemStats::getNumCpus(), 0, Thread::Priority::normal)
ThreadPool::ThreadPool (int numberOfThreads,
size_t threadStackSizeBytes,
Thread::Priority desiredThreadPriority)
: ThreadPool { ThreadPoolOptions{}.withNumberOfThreads (numberOfThreads)
.withThreadStackSizeBytes (threadStackSizeBytes)
.withDesiredThreadPriority (desiredThreadPriority) }
{
}

View file

@ -140,6 +140,51 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ThreadPoolJob)
};
//==============================================================================
/**
A set of threads that will run a list of jobs.
When a ThreadPoolJob object is added to the ThreadPool's list, its runJob() method
will be called by the next pooled thread that becomes free.
@see ThreadPoolJob, Thread
@tags{Core}
*/
struct ThreadPoolOptions
{
/** The name to give each thread in the pool. */
[[nodiscard]] ThreadPoolOptions withThreadName (String newThreadName) const
{
return withMember (*this, &ThreadPoolOptions::threadName, newThreadName);
}
/** The number of threads to run.
These will be started when a pool is created, and run until the pool is destroyed.
*/
[[nodiscard]] ThreadPoolOptions withNumberOfThreads (int newNumberOfThreads) const
{
return withMember (*this, &ThreadPoolOptions::numberOfThreads, newNumberOfThreads);
}
/** The size of the stack of each thread in the pool. */
[[nodiscard]] ThreadPoolOptions withThreadStackSizeBytes (size_t newThreadStackSizeBytes) const
{
return withMember (*this, &ThreadPoolOptions::threadStackSizeBytes, newThreadStackSizeBytes);
}
/** The desired priority of each thread in the pool. */
[[nodiscard]] ThreadPoolOptions withDesiredThreadPriority (Thread::Priority newDesiredThreadPriority) const
{
return withMember (*this, &ThreadPoolOptions::desiredThreadPriority, newDesiredThreadPriority);
}
String threadName { "Pool" };
int numberOfThreads { SystemStats::getNumCpus() };
size_t threadStackSizeBytes { Thread::osDefaultStackSize };
Thread::Priority desiredThreadPriority { Thread::Priority::normal };
};
//==============================================================================
/**
@ -156,25 +201,35 @@ class JUCE_API ThreadPool
{
public:
//==============================================================================
/** Creates a thread pool based on the provided options.
Once you've created a pool, you can give it some jobs by calling addJob().
@see ThreadPool::ThreadPoolOptions
*/
explicit ThreadPool (const ThreadPoolOptions& options);
/** Creates a thread pool based using the default arguments provided by
ThreadPoolOptions.
Once you've created a pool, you can give it some jobs by calling addJob().
@see ThreadPoolOptions
*/
ThreadPool() : ThreadPool { ThreadPoolOptions{} } {}
/** Creates a thread pool.
Once you've created a pool, you can give it some jobs by calling addJob().
@param numberOfThreads the number of threads to run. These will be started
immediately, and will run until the pool is deleted.
@param threadStackSize the size of the stack of each thread. If this value
is zero then the default stack size of the OS will
be used.
@param priority the desired priority of each thread in the pool.
@param numberOfThreads the number of threads to run. These will be started
immediately, and will run until the pool is deleted.
@param threadStackSizeBytes the size of the stack of each thread. If this value
is zero then the default stack size of the OS will
be used.
@param priority the desired priority of each thread in the pool.
*/
ThreadPool (int numberOfThreads, size_t threadStackSize = 0, Thread::Priority priority = Thread::Priority::normal);
/** Creates a thread pool with one thread per CPU core.
Once you've created a pool, you can give it some jobs by calling addJob().
If you want to specify the number of threads, use the other constructor; this
one creates a pool which has one thread for each CPU core.
@see SystemStats::getNumCpus()
*/
ThreadPool();
ThreadPool (int numberOfThreads,
size_t threadStackSizeBytes = Thread::osDefaultStackSize,
Thread::Priority desiredThreadPriority = Thread::Priority::normal);
/** Destructor.

View file

@ -306,7 +306,7 @@ namespace DragAndDropHelpers
// We need to make sure we don't do simultaneous text and file drag and drops,
// so use a pool that can only run a single job.
ThreadPool pool { 1 };
ThreadPool pool { ThreadPoolOptions{}.withNumberOfThreads (1) };
};
JUCE_IMPLEMENT_SINGLETON (ThreadPoolHolder)