У меня вопрос по поводу вызова методов из разных потоков. Ну, я использую драйвер WinUSB для связи с USB-устройством. У меня есть отдельный поток для чтения данных с устройства. Команды для устройства задаются в основном потоке. На самом деле я использую методы WinUSB_WritePipe и WinUSB_ReadPipe для выполнения таких операций. В потоке, где читаются данные, я использую асинхронный метод чтения с перекрывающейся структурой и WaitForMultipleObject. У моего устройства есть некоторые функции, которые мне нужно установить, и это делается через графический интерфейс в основном потоке.
Я наблюдаю странное поведение. Мой вопрос в том, нужно ли мне блокировать вызовы (например.с мьютексом) к этим методам, поэтому только один поток одновременно обращается к методу или вызывает его.
СТАРЫЙ ПУТЬ:
type TMyThread = TThread
protected
procedure Execute; override;
end;
procedure TMyThread.Execute;
begin
while not Terminated do
begin
WinUsb_ReadPipe(Pipe, Amount, Overlapped)
ErrNo := GetLastError;
if ErrNo = ERROR_IO_PENDING then
begin
wRes = WaitForMultipleObjects(2, @HndEvt, false);
if wRes = WAIT_OBJECT_0 then
begin
ResetEvent(Overlapped.hEvent);
WinUSB_GetOVerlappedResult
DoSomethingWithData; // Do something
end;
end;
end;
end;
MainThread:
begin
// Set device sample rate
WinUSB_WritePipe (Pipe, Amount, Data, ...)
end;
НОВЫЙ ПУТЬ:
type TMyThread = TThread
protected
procedure Execute; override;
public
procedure Lock;
procedure Unlock;
constructor Create(ASuspended: boolean); override;
destructor Destroy; override;
end;
constructor TMyThread.Create(ASuspended: boolean);
begin
hMtx := CreateMutex(nil, false, nil);
end;
destructor TMyThread.Destroy(ASuspended: boolean);
begin
CloseHandle(hMtx);
end;
procedure TMyThread.Lock;
begin
WaitForSingleObject(hMtx, 10000);
end;
procedure TMyThread.Unlock;
begin
ReleaseMutex(hMtx);
end;
procedure TMyThread.Execute;
begin
while not Terminated do
begin
Lock;
WinUsb_ReadPipe(Pipe, Amount, Overlapped)
Unlock;
ErrNo := GetLastError;
if ErrNo = ERROR_IO_PENDING then
begin
wRes = WaitForMultipleObjects(2, @HndEvt, false);
if wRes = WAIT_OBJECT_0 then
begin
ResetEvent(Overlapped.hEvent);
Lock;
WinUSB_GetOVerlappedResult
Unlock;
DoSomethingWithData; // Do something
end;
end;
end;
end;
MainThread:
begin
// Set device sample rate
Lock; // same mutex as in TMYThread
WinUSB_WritePipe (Pipe, Amount, Data, ...)
Unlock; // same mutex as in TMYThread
end;
Это очень упрощенный код, предназначенный только для описания моей проблемы и не отражающий мои навыки программирования. :) Конечно, с тем же мьютексом я блокирую вызов того же метода в основном потоке.
Надеюсь, я описал свою проблему как можно проще... так что еще раз: нужно ли блокировать вызовы этих методов в разных потоках?
Заранее спасибо за уделенное время и ответы. Я очень ценю это!
Бр, Никс