Несмотря на то, что вы создаете только одну задачу для связывающегося задания, система копирует эту задачу для каждого работника, который запускает задание. Например, если коммуникационное задание работает с четырьмя работниками, Tasks
свойство задания содержит четыре объекта задачи. Первая задача в Tasks
задания свойство соответствует задаче, выполняемой работником,
labindex
является 1
и так далее, чтобы ID
свойство для объекта задачи и labindex
для работника, который выполнял эту задачу, имеют то же значение. Поэтому последовательность результатов, возвращенных fetchOutputs
функция соответствует значению labindex
и к порядку задач в Tasks
работы свойство.
Поскольку код, выполняемый в одном рабочем процессе для связывающегося задания, может блокировать выполнение до тех пор, пока какой-либо соответствующий код не будет выполнен на другом рабочем месте, потенциал взаимоблокировки существует в передаче заданий. Это, скорее всего, произойдет при передаче данных между работниками или при постановке кода в зависимость от labindex
в if
оператор. Некоторые примеры иллюстрируют общие подводные камни.
Предположим, у вас есть кодовый распространенный массив D
, и вы хотите использовать gather
функция для сборки всего массива в рабочей области одного рабочего.
if labindex == 1 assembled = gather(D); end
Причина сбоя состоит в том, что gather
функция требует связи между всеми работниками, через которые распределен массив. Когда if
оператор ограничивает выполнение одним работником, другие работники, необходимые для выполнения функции, не выполняют оператор. В качестве альтернативы можно использовать gather
сам собирать данные в рабочую область одного работника: assembled = gather(D, 1)
.
В другом примере предположим, что вы хотите перенести данные от каждого работника к следующему работнику справа (определяемому как следующий выше labindex
). Сначала вы задаете для каждого работника, каковы рабочие слева и справа.
from_lab_left = mod(labindex - 2, numlabs) + 1; to_lab_right = mod(labindex, numlabs) + 1;
Затем попробуйте передать данные по звонку.
labSend (outdata, to_lab_right); indata = labReceive(from_lab_left);
Причина сбоя этого кода заключается в том, что, в зависимости от размера передаваемых данных, labSend
функция может блокировать выполнение в рабочем режиме, пока соответствующий принимающий рабочий не выполнит свое labReceive
функция. В этом случае все работники пытаются отправить одновременно, и ни один из них не пытается получить во время labSend
блокирует их. Другими словами, никто из работников не добирается до своих labReceive
операторы, потому что все они заблокированы в labSend
оператор. Чтобы избежать этой конкретной проблемы, вы можете использовать labSendReceive
функция.