MATLAB 同步代码

3

在MATLAB中,与Java的"synchronized"相当的是什么?

假设我有两个计时器,它们都可以修改一个变量(即矩阵)M。如果它们同时触发,它们会同时尝试更改M吗(这可能会导致错误)?MATLAB是否自动同步这些操作?


我必须说这是一个可怕的限制。没有办法打断一个昂贵但优先级较低的操作(即绘图),以进行快速但优先级更高的操作(实时控制)。 - Kevin Kostlan
1个回答

3

Matlab是99%单线程的(另外1%与此问题无关)。因此,没有synchronized关键字可用。

然而,一些操作是可中断的,这意味着GUI回调或定时器可以在意料之外的时间暂停操作。这可能会导致在多线程系统中观察到的一些相同问题。

为了防止中断,在可用时使用interruptible属性(通常在GUI对象上)。这应该处理在处理GUI回调时需要防止可重入行为的需求。例如:

set(gcf,'Interruptible','off')

然而,这并不能处理与计时器相关的中断。
看起来两个计时器无法相互中断,因此不需要同步。 但是,计时器可能会中断主活动。
经过一些测试,这可能发生在pausedrawnowfiguregetframe调用附近,这在文档中已经说明。 它也可能发生在其他一些调用附近,包括一些tic/toc调用和对Java的调用。
我不知道计时器或函数的Interruptible属性是否有类似于Interruptible属性的并行,尽管可能需要。 根对象0具有一个Interruptible属性,但是它没有任何效果(根据文档和确认)。
注意:这是我之前提供的答案的重大变化(请参见历史记录),代表最近的学习。 我以前的示例使用了两个计时器,它们似乎可以互相排除干扰。 此示例使用一个计时器加上主函数操作。
下面包含一个示例,演示了一个不可中断的情况和两个函数some_work被中断的情况。
function minimum_synchronization_example

%Defune functions to test for interruptability
%(these are all defined at the bottom of the file)
fnList = {
    @fn_expectedNoInterruption
    @fn_expectedInterruption
    @fn_unexpectedInterruption
    };
for ix = 1:length(fnList)
    disp(['---Examples using ' func2str(fnList{ix}) '--------'])
    test_subfunction_for_interrupt_allowed(fnList{ix});
end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function test_subfunction_for_interrupt_allowed(fn)
%Setup and start a timer to execute "some_work"
t1 = timer();
set(t1,...
    'Name','PerformSomeWorkTimer1', ...
    'TimerFcn', @(~,~) some_work('Timer-1', fn), ...
    'ExecutionMode','fixedSpacing', ...
    'Period', 0.4, ...
    'TasksToExecute', 6, ...
    'BusyMode', 'drop')
start(t1);

%Then immediately execute "some_work" from the main function
for ix = 1:6
    some_work('MainFun', fn);
    pause(0.2);
end

%The timer and the loop take about the same amount of time, stop and delete
%the timer before moving on
stop(t1);
delete(t1);
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function some_work(displayString, subFunctionWhichMayAllowInterrupts)
%Initialize persistent, if needed.
%This records then umber of active calls to this function.
persistent entryCount
if isempty(entryCount)
    entryCount = 0;
end

%Record entry
entryCount = entryCount+1;
tic;

%Perform some work  (Inverting a 3000-by-3000 matrix takes about 1 sec on my computer)
[~] = inv(randn(3000));

%Run subfunction to see if it will be interrupted
subFunctionWhichMayAllowInterrupts();

%Display results. How many instances of this function are currently active?
if entryCount>1;
    strWarning = 'XXX ';
else
    strWarning = '    ';
end
disp([strWarning ' <' sprintf('%d',entryCount) '> [' displayString '] ; Duration: ' sprintf('%7.3f',toc)]);

%Record exit
entryCount = entryCount-1;
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function fn_expectedNoInterruption
x = 1+1;
end

function fn_expectedInterruption
drawnow;
end

function fn_unexpectedInterruption
m = java.util.HashMap();
end

值得注意的是,MATLAB可以在定时器回调函数中处理事件队列的其余部分(即调用其他定时器的回调函数),但前提是在定时器回调函数中放置一个对drawnowdrawnow update的调用。然而,这仍然是单线程行为。 - wakjah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接