Update object properties on change of another objects property within parfor

17 次查看(过去 30 天)
I'd like to use objects in parfor in a way that an update of a first objects property causes the update of properties of the second object.
To illustrate my problem, I've created the following two classes:
classdef class1 < handle
properties (Access=private)
value
end
events
UpdateValue
end
methods
function obj = class1(value)
obj.value = value;
end
function obj = changeValue(obj,newValue)
obj.value = newValue;
notify(obj,'UpdateValue');
end
end
end
and
classdef class2 < handle
properties
mode (1,1) logical = false
propertyStruct
end
properties (Access=private)
property1
end
methods
function obj = class2(var)
obj = obj.setChangingProperty(var);
end
function property1 = getProperty1(obj)
if obj.mode
property1 = obj.propertyStruct.Property1.value;
else
property1 = obj.property1;
end
end
function obj = setChangingProperty(obj,var)
if isa(var,'class1')
obj.property1 = var.value;
addlistener(var,'UpdateValue',@(src,evnt) obj.ChangeListenerProperty(src,evnt,'property1'));
obj.propertyStruct.Property1 = var;
end
end
function obj = ChangeListenerProperty(obj,src,~,varargin)
obj.(varargin{1}) = src.value;
end
function [val1,val2] = aFunction(obj)
val1 = obj.getProperty1();
val2 = obj.property1;
end
end
end
Now I'd like to use objects created by these classes in parfor. Therefore, class2 has the property mode, which can be set to true (in case the object is used in parfor) or false elsewise. A test script might look like this:
% create object which value can be changed
var = class1(1);
% create object that takes var as an input
c2 = class2(var);
% deactivate parfore mode
c2.mode = 0;
result = zeros(1,2);
% change var in parfor loop
parfor k = 1
var.changeValue(5);
[a,b] = c2.aFunction();
result(k,:) = [a,b];
end
disp(result);
% reset var
var.changeValue(1);
% activate parfor mode
c2.mode = 1;
result = zeros(1,2);
% change var in parfor loop
parfor k = 1
var.changeValue(5);
[a,b] = c2.aFunction();
result(k,:) = [a,b];
end
disp(result);
So in the first case, the change of var's property value didn't cause any change in c2 - as far as I'm concerned this is due to the inability to use listeners within parfor. On the opposite, in the second case c2.property1 is changed as I'm using the object that is saved in the propertyStruct. To be able to access the updated value an aditional method getProperty1 is needed which returns the updated property based on the value of the property mode. Just calling obj.property1 returns the old value.
One solution would be to discard the use of listeners within my objects, but I'd like to use them outside of parfor loops as it's much faster.
My problem is, that within class2 I need to use the method setChangingProperty instead of just writing obj.property = var within the constructor to set a property that can be updated. Moreover, in any of the other methods the updated value of property1 can only be accessed by the method getProperty1. Additionally, it should be possible to have multiple properties like property1.
Is there a more elegant way to update properties of one object on change of another one within parfor?

回答(1 个)

Poorna
Poorna 2023-12-6
Hi Tido Kubatschek,
I understand that you are trying to use event triggers inside “parfor” loops.
parfor” loops execute in separate processes and events doesn’t work inside parfor” loops. In your code you could try printing a debug message inside the “ChangeListenerProperty” function to see how many times it is called. There are a total of 3 calls to the “changeValue” function but instead you will only see one debug message printed caused by the 2nd call to the “changeValue” function outside the “parfor” loop.
Instead of using the built-in “events” by MATLAB, you could try mimicking the behaviour by explicitly calling the trigger function every time the “changeValue” function is called inside the parfor loop as below.
  • You could create a simple update function to update the “c2” variable’s “property1” taking “class1” object as input like below.
function obj = updateVal(obj, var)
obj.property1 = var.value;
end
  • Then, you can call this function following every call to the “changeValue” function inside “parfor” loop like below.
parfor k = 1
var.changeValue(5);
c2.updateVal(var);
end
Hope this Helps!
Best regards,
Poorna.

类别

Help CenterFile Exchange 中查找有关 Parallel for-Loops (parfor) 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by