Проблема с многопоточностью

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Проблема с многопоточностью

Сообщение Dmitriy » 15.10.2010 11:12:40

Здравствуйте. Портирую с Delphi 2010 на FPC 2.4.0 приложение, 20000 строк. Проблема возникла с потоками. В этом посте под потоками подразумеваются потоки Windows, созданные с помощью CreateThread, класс TThread не используется. В случайные моменты времени в разных местах ошибки SIGSEGV или AV. Удалось получить воспроизводимый случай (программа бессмысленная, но не важно):
Код: Выделить всё
program project1;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes, SysUtils, CustApp,

  { you can add units after this }
  Windows,
  ActiveX;



{$IFDEF WINDOWS}{$R project1.rc}{$ENDIF}


function ThreadProc(pDeffered:pointer):dword;stdcall;
const
  TIME_TO_SLEEP_DURING_ANIMATION = 660;
var
  FSEFirst, FSELast, FSEinx:integer;
  FSE:pointer;
  StubTextureInx :integer;

  AtlasInx:integer;
  TexLeft:Single;
  TexRight:Single;
  TexBottom:Single;
  TexTop:Single;
  msg:tagMSG;
  path:WideString;
  OleInitRes:HRESULT;
  path2:array[0..MAX_PATH-1] of WideChar;
  i:integer;
begin
  result := 0;



  OleInitRes := OleInitialize(nil);


  FSEFirst := 1;
  FSELast := 50;
  i:= 4;
  path := 'grehrh';
  for FSEinx := FSEFirst to FSELast do
  begin
    GetFileAttributesW('c:\windows');
    i := i + 1;
    GetFileAttributesW('c:\windows');
  end;

  OleUninitialize;

end;

var
   i:integer;


begin


    for i := 0 to 10 do
      CreateThread(nil, 0, @ThreadProc,  nil,0, threadID);


   MessageBoxW(0, 'OK','caption',0);
end.


У меня на Win7 выдает SIGSEGV. Видимо, дело в строке path := 'grehrh'; В FPC опыта нет, что здесь не так?
И сразу хочу спросить, за исключением общих правил работы с потоками (типа избегать глобальных переменных) есть ли специфические требования FPC?
Особенно какие еще вещи запрещено делать из потоковой функции? Буду благодарен за любые FPC-специфичные предостережения при работе с потоками.
Dmitriy
незнакомец
 
Сообщения: 2
Зарегистрирован: 15.10.2010 10:53:03

Re: Проблема с многопоточностью

Сообщение Bupyc » 15.10.2010 11:46:41

Вообще работать с потоками напрямую через АПИ в Delphi и, видимо в FPC, это дурной тон.
Если мне память не изменяет, в дельфе было так: если запускается экземпляр TThread, то инкрементируется внутренний счётчик потоков и устанавливается в True глобальная переменная IsMultithread. Эта переменная используется в во внутреннем менеджере памяти. Там присутствуют конструкции типа

Код: Выделить всё

if IsMultithread then EnterCriticalSection(....);

// что то делаем

if IsMultithread then LeaveCriticalSection(....);



Когда Вы используете виндовые АПИ, переменная IsMultithread не выставлется в True. В приложении, которое по факту является мультипоточным, не работают синхронизации.
В приложении на дельфи менеджер памяти используется в том числе и при работе со строками. Поэтому Вы получаете то, что получаете, а именно, падение приложения в произвольных и, с виду безобидных, местах.

Быстрым решением, может служить ручная установка переменной IsMultithread в True, либо использование класса TThread, либо функции BeginThread вместо CreateThread.

Всё сказанное относится к дельфи, но думаю, что и в FPC то же самое.

P.S. Такая ситуация была у меня примерно лет 10-11 назад. Я тогда месяц потратил, что бы понять, что происходит.

Добавлено спустя 3 минуты 47 секунд:
Вот что пишет дельфёвый хелп по этому поводу.

Код: Выделить всё
IsMultiThread is set to true to indicate that the memory manager should support multiple threads. IsMultiThread is set to true by BeginThread and class factories.
Bupyc
постоялец
 
Сообщения: 137
Зарегистрирован: 29.08.2007 18:22:42

Re: Проблема с многопоточностью

Сообщение pda » 15.10.2010 12:06:35

Код: Выделить всё
OleUninitialize;

OleUninitialize внутри вызывает CoUninitialize.
Функция CoUninitialize имеет ошибку в реализации (на всех Windows до 2003 гарантированно), освобождая библиотеки раньше, чем объект ошибки, что приводит к Access Violation в модуле ole32.dll.

См. http://rsdn.ru/Forum/Info/FAQ.com.counitialize.bug.aspx

Кроме того вы не ждёте пока ваши потоки завершаться.
Аватара пользователя
pda
постоялец
 
Сообщения: 303
Зарегистрирован: 27.05.2005 19:59:53

Re: Проблема с многопоточностью

Сообщение Dmitriy » 15.10.2010 12:31:04

Вообще работать с потоками напрямую через АПИ в Delphi и, видимо в FPC, это дурной тон.


Да, проблема решена, Вы правы. В документации FPC (prog.pdf) ясно сказано:
All routines for threading are available in the system unit, under the form of a thread manager. A
thread manager must implement some basic routines which the RTL needs to be able to support
threading. For Windows, a default threading manager is integrated in the system unit. For other
platforms, a thread manager must be included explicitly by the programmer. On systems where
posix threads are available, the cthreads unit implements a thread manager which uses the C POSIX
thread library. No native pascal thread library exists for such systems.
Although it is not forbidden to do so, it is not recommended to use system-specific threading routines:
The language support for multithreaded programs will not be enabled, meaning that threadvars will
not work, the heap manager will be confused which may lead to severe program errors.

На практике это означает следующее. Работая в FPC под Windows, никогда не используйте функцию CreateThread!
Иначе программа будет падать в случайные моменты времени на AV в случайных местах кода.
В FPC поддерживается функция BeginThread, один из ее прототипов
Код: Выделить всё
function BeginThread(sa : Pointer;
stacksize : SizeUInt;
ThreadFunction : tthreadfunc;
p : pointer;
creationFlags : dword;
var ThreadId : TThreadID) : TThreadID;

совпадает с аналогом из Delphi, необходимо использовать ее или TThread.
Всем респект за ответы!
Dmitriy
незнакомец
 
Сообщения: 2
Зарегистрирован: 15.10.2010 10:53:03


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

Рейтинг@Mail.ru