Jobs Manual

About

A job is a threaded, reusable, independent work item (task). It can be queued to be executed with other jobs in a (parallel) pipeline.

Job

A custom job is based on maxon::JobInterfaceTemplate, maxon::JobResultInterface and maxon::JobInterface. The custom class contains data and implements the function call operator with the actual workload. A job instance is based on maxon::JobRef.

Warning
Make sure that a job has no additional, hidden dependencies like for example executing parallelized code internally.
// This example shows a job that returns a value.
// FactorialJob calculates the factorial of the given number.
class FactorialJob : public maxon::JobInterfaceTemplate<FactorialJob, maxon::UInt>
{
public:
FactorialJob() { };
{
_n = n;
}
// function operator with the actual workload
maxon::Result<void> operator ()()
{
// 0! and 1! are 1
maxon::UInt factorial = 1;
if (MAXON_LIKELY(_n > 1))
{
factorial = _n;
while (_n > 1)
{
--_n;
factorial *= _n;
}
}
// store result
return SetResult(std::move(factorial));
}
private:
maxon::UInt _n = 0;
};
Definition: job.h:1098
const Py_UNICODE size_t n
Definition: unicodeobject.h:1184
#define MAXON_IMPLICIT
Definition: apibase.h:172
UInt64 UInt
unsigned 32/64 bit int, size depends on the platform
Definition: apibase.h:189
#define MAXON_LIKELY(...)
Definition: compilerdetection.h:403
ResultOk< void > SetResult()
Definition: job.h:1059

A job can also implement:

A job has to be enqueued in a queue to be executed (see job queue below):

// This example creates and starts a job that will return a result value.
// create and start job
const maxon::UInt n = 10;
job.Enqueue(); // enqueue the job in the current queue and start
// wait and get result
const maxon::UInt factorial = job.GetResult() iferr_return;
DiagnosticOutput("@! = @", n, factorial);
static auto Create(ARGS &&... args)
Definition: apibase.h:2773
#define DiagnosticOutput(formatString,...)
Definition: debugdiagnostics.h:176
#define iferr_return
Definition: resultbase.h:1519

A running job can be cancelled:

// This example cancels the given job and waits for it to finish.
// cancel the given job
job.CancelAndWait();

These observers can be used to react to certain events:

Further utility function are:

Static utility functions are:

Job Group

Jobs can be organized in job groups. These groups are used to execute and wait for multiple jobs simultaneously. The jobs of a group typically belong together. The jobs are executed as efficiently as possible.

The maxon::JobGroupRef members are:

// This example creates a new job group and adds lambda functions to it.
// create group
for (const maxon::Url& file : files)
{
// add lambda function
group.Add(
[file]()
{
CreateFileHash(file) iferr_ignore("Lambda can't handle errors."_s);
}
// enqueue jobs and wait
group.Enqueue();
group.Wait();
Reference to a group (JobGroupInterface).
Definition: jobgroup.h:403
Bool Wait(TimeValue timeout=TIMEVALUE_INFINITE, WAITMODE mode=WAITMODE::DEFAULT) const
Definition: jobgroup.h:474
const JobGroupRef & Enqueue(JobQueueInterface *queue=JOBQUEUE_CURRENT) const
Definition: jobgroup.h:427
static ResultMemT< JobGroupRef > Create(JOBGROUPFLAGS flags=JOBGROUPFLAGS::DEFAULT)
Definition: jobgroup.h:414
Result< void > Add(T &&obj) const
Definition: jobgroup.h:523
for(i=0;i< length;i++)
Definition: unicodeobject.h:61
The maxon namespace contains all declarations of the MAXON API.
Definition: autoweight.h:14
#define iferr_ignore(...)
Definition: resultbase.h:1484
const char const char const char * file
Definition: object.h:439
// This example creates a new job group and adds newly created jobs to it.
// create group
for (const maxon::Url& file : files)
{
// create and add job
group.Add(job) iferr_return;
}
// enqueue jobs and wait
group.Enqueue();
group.Wait();
// This example creates a new job group and adds generic jobs to it.
// create group
for (const maxon::Url& file : files)
{
// add generic job defined by a lambda function
{
return CreateFileHash(file);
group.Add(job) iferr_return;
}
// enqueue jobs and wait
group.Enqueue();
group.Wait();
Reference to a job (JobInterface).
Definition: job.h:1222
static auto Create(FN &&src, ARGS &&... args) -> ResultMemT< JobResultRef< decltype(src(std::forward< ARGS >(args)...))>>
Definition: job.h:1245
// This example creates a new job group and adds an array of jobs to it
// create group
// prepare array of jobs
maxon::BaseArray<FileHashJob> jobs;
jobs.EnsureCapacity(files.GetCount()) iferr_return;
for (const maxon::Url& file : files)
{
// create job
FileHashJob& job = jobs.Append() iferr_return;
// init job
job.SetFile(file) iferr_return;
}
group.Add(jobs) iferr_return;
// enqueue jobs and wait
group.Enqueue();
group.Wait();
Int GetCount(const ITERABLE &iterable)
Definition: collection.h:37

Jobs that do belong to a job group can handle sub-jobs:

Queue

Jobs are added to a queue which executes these jobs. A queue provides worker threads and distributes the jobs.

Note
Typically it is not needed to create a custom queue. maxon::JOBQUEUE_CURRENT should be used.

Default job queues are:

It is possible to manually create queues in order to organize job execution.

Note
Functions like maxon::JobInterface::Enqueue() or maxon::JobGroupRef::Enqueue() add the job or jobs to the current job queue if no argument is given.

Further Reading