Компьютерный форум
Правила
Вернуться   Компьютерный форум > Форум программистов > Языки программирования > Oberon
Перезагрузить страницу Реализация модуля thread
Ответ
 
Опции темы Опции просмотра
  (#1 (permalink)) Старый
o_nick o_nick вне форума
Новичок
 
Сообщений: 4
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 13.05.2004
По умолчанию Реализация модуля thread - 13.05.2004, 20:19

А вот в ЧЯ реализован subj? Если да то ткните меня носом в модуль (ну и там мануалку).

спасибо.
Ответить с цитированием
  (#2 (permalink)) Старый
S.Yu.Gubanov S.Yu.Gubanov вне форума
Member
 
Сообщений: 587
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 03.12.2002
По умолчанию 21.05.2004, 11:56

В Component Pascal - нет. Если интересуетесь многопоточностью встроенной непосредственно в язык программирования, то обратите внимание на Active Oberon, Zonnon, Ada, ...

http://qnxclub.net/files/articles/razm/razm.html
Ответить с цитированием
  (#3 (permalink)) Старый
o_nick o_nick вне форума
Новичок
 
Сообщений: 4
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 13.05.2004
По умолчанию Re: thread - 04.08.2004, 18:40

Кажется можно всех поздравить.
ЧЯ пока не ругнулась ни на один мой поток.
И сборщик мусора вроде нормально работает.
Ответить с цитированием
  (#4 (permalink)) Старый
S.Yu.Gubanov S.Yu.Gubanov вне форума
Member
 
Сообщений: 587
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 03.12.2002
По умолчанию Re: thread - 05.08.2004, 11:24

Цитата:
Originally posted by o_nick
[b]Кажется можно всех поздравить.
ЧЯ пока не ругнулась ни на один мой поток.
И сборщик мусора вроде нормально работает.
Поздравляю!
Поделитесь приобретенным опытом с общественностью?
Ответить с цитированием
  (#5 (permalink)) Старый
S.Yu.Gubanov S.Yu.Gubanov вне форума
Member
 
Сообщений: 587
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 03.12.2002
По умолчанию 11.01.2005, 18:57

Примерчик...

Код:
MODULE TestThreads;

IMPORT WinApi, StdLog;

TYPE
    Item = POINTER TO RECORD
  time: LONGINT;
  thread, num: INTEGER;
  next: Item;
  ballast: ARRAY 1000 OF BYTE;
    END;

CONST
    MaxCount = 1000;
    
VAR
    CriticalSection: WinApi.RTL_CRITICAL_SECTION;
    ItemListFront, ItemListBack: Item;
    count: INTEGER;
    t0: LONGINT;
    


(* Действие выполняемое потоком  *)
PROCEDURE Action(IpParameter: INTEGER): INTEGER;
VAR x: Item; num: INTEGER;
BEGIN
    num := 0;
    WHILE count < MaxCount DO
  WinApi.EnterCriticalSection(CriticalSection);
  IF count < MaxCount THEN
      INC(count); INC(num);
      NEW(x); 
      x.time := WinApi.GetTickCount() - t0; 
      x.thread := IpParameter;
      x.num := num;
      IF ItemListBack # NIL THEN ItemListBack.next := x END;
      ItemListBack := x;
      IF ItemListFront = NIL THEN ItemListFront := ItemListBack END
  END;
  WinApi.LeaveCriticalSection(CriticalSection);
  WinApi.Sleep(1000);
    END;
    WinApi.ExitThread(0);
    RETURN 0;
END Action;




PROCEDURE Main*;
CONST N = 300; (* Создадим 300 потоков!!! *)
VAR 
    a, i: INTEGER; 
    h: ARRAY N OF WinApi.HANDLE; 
    t: ARRAY N OF INTEGER;
    x: Item;
BEGIN
    count := 0;
    ItemListFront := NIL;
    ItemListBack := NIL;
    
    WinApi.InitializeCriticalSection(CriticalSection);
    
    t0 := WinApi.GetTickCount();
    FOR i := 0 TO N-1 DO h[i] := WinApi.CreateThread(NIL, 0, Action, i+1, {}, t[i]) END;
    
    a := WinApi.WaitForMultipleObjects(N, h[0], 1, WinApi.INFINITE);
    
    FOR i := 0 TO N-1 DO a := WinApi.CloseHandle(h[i]) END;
    WinApi.DeleteCriticalSection(CriticalSection);

    StdLog.String('Items count = '); StdLog.Int(count);
    StdLog.Ln;
    x := ItemListFront;
    i := 1;
    WHILE x # NIL DO
  StdLog.Int(i); StdLog.String(")"); 
  StdLog.Int(x.thread); StdLog.Int(x.num); StdLog.Int(x.time); StdLog.Ln;
  INC(i); x := x.next
    END;
    ItemListFront := NIL;
    ItemListBack := NIL;
END Main;

END TestThreads.
Ответить с цитированием
Ads.
  (#6 (permalink)) Старый
Phinc Phinc вне форума
Member
 
Сообщений: 32
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 15.10.2004
По умолчанию 13.01.2005, 10:55

Выполнение программы дает ошибку и Windows закрывает BlackBox.
Ответить с цитированием
  (#7 (permalink)) Старый
S.Yu.Gubanov S.Yu.Gubanov вне форума
Member
 
Сообщений: 587
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 03.12.2002
По умолчанию 13.01.2005, 13:16

Цитата:
Originally posted by Phinc
[b]Выполнение программы дает ошибку и Windows закрывает BlackBox.
Да, действительно... Когда я увеличил количество потоков до N=330, то и у меня возникла ошибка (Windows XP SP2, 256Mb. BlackBox 1.4 и 1.5 BETA).

Оказывается WinApi.WaitForMultipleObjects() возвращает WAIT_FAILED = -1

Забавно. Потоки дело тонкое...
Ответить с цитированием
  (#8 (permalink)) Старый
S.Yu.Gubanov S.Yu.Gubanov вне форума
Member
 
Сообщений: 587
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 03.12.2002
По умолчанию 13.01.2005, 13:58

Код:
MODULE TestThreads;

IMPORT WinApi, StdLog;

TYPE
    Item = POINTER TO RECORD
  time: LONGINT;
  thread, num: INTEGER;
  next: Item;
  ballast: ARRAY 100000 OF BYTE;
    END;

CONST
    MaxItemsCount = 1000;
    
VAR
    CriticalSection: WinApi.RTL_CRITICAL_SECTION;
    ItemListFront, ItemListBack: Item;
    items_count, threads_count: INTEGER;
    t0: LONGINT;
    
PROCEDURE IncThreadsCount();
BEGIN
    WinApi.EnterCriticalSection(CriticalSection);
    INC(threads_count);
    WinApi.LeaveCriticalSection(CriticalSection);
END IncThreadsCount;

PROCEDURE DecThreadsCount();
BEGIN
    WinApi.EnterCriticalSection(CriticalSection);
    DEC(threads_count);
    WinApi.LeaveCriticalSection(CriticalSection);
END DecThreadsCount;

PROCEDURE NewItem(IpParameter, num: INTEGER);
VAR x: Item;
BEGIN
    WinApi.EnterCriticalSection(CriticalSection);
    IF items_count < MaxItemsCount THEN
  NEW(x); 
  IF x # NIL THEN
      INC(items_count); INC(num);
      x.time := WinApi.GetTickCount() - t0; 
      x.thread := IpParameter;
      x.num := num;
      IF ItemListBack # NIL THEN ItemListBack.next := x END;
      ItemListBack := x;
      IF ItemListFront = NIL THEN ItemListFront := ItemListBack END
  END
    END;
    WinApi.LeaveCriticalSection(CriticalSection);
END NewItem;

PROCEDURE Action(IpParameter: INTEGER): INTEGER;
VAR num: INTEGER;
BEGIN
    IncThreadsCount(); num := 0;
    WHILE items_count < MaxItemsCount DO
  NewItem(IpParameter, num);
  WinApi.Sleep(100)
    END;
    DecThreadsCount(); WinApi.ExitThread(0); RETURN 0
END Action;

PROCEDURE Main*;
CONST N = 1000;
VAR 
    a, i: INTEGER; 
    h: ARRAY N OF WinApi.HANDLE; 
    t: ARRAY N OF INTEGER;
    x: Item;
BEGIN
    items_count := 0; ItemListFront := NIL; ItemListBack := NIL;
    
    WinApi.InitializeCriticalSection(CriticalSection);
    
    t0 := WinApi.GetTickCount();

    FOR i := 0 TO N-1 DO h[i] := WinApi.CreateThread(NIL, 0, Action, i+1, {}, t[i]) END;

    (* Доморощенный WaitForMultipleObjects вместо Виндозного... *)
    REPEAT
  a := threads_count;
  StdLog.String('threads count = '); StdLog.Int(a); StdLog.Ln;
  WinApi.Sleep(100);      
    UNTIL a = 0;
    
    FOR i := 0 TO N-1 DO a := WinApi.CloseHandle(h[i]) END;
    WinApi.DeleteCriticalSection(CriticalSection);
(*
    StdLog.Ln; StdLog.String('Items count = '); StdLog.Int(items_count); StdLog.Ln;
    x := ItemListFront; i := 1;
    WHILE x # NIL DO
  StdLog.Int(i); StdLog.String(")"); 
  StdLog.Int(x.thread); StdLog.Int(x.num); StdLog.Int(x.time); StdLog.Ln;
  INC(i); x := x.next
    END;
*)    
    ItemListFront := NIL; ItemListBack := NIL;
END Main;

END TestThreads.
Ответить с цитированием
  (#9 (permalink)) Старый
S.Yu.Gubanov S.Yu.Gubanov вне форума
Member
 
Сообщений: 587
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 03.12.2002
По умолчанию 13.01.2005, 14:13

А... Дошло....

Надо в первом примере вместо WaitForMultipleObject написать, например, вот это:

Код:
FOR i := 0 TO N-1 DO a := WinApi.WaitForSingleObject(h[i], WinApi.INFINITE) END;

Это потому, что в функцию WaitForMultipleObject слишком много объектов передавать нельзя, можно не более чем MAXIMUM_WAIT_OBJECTS = 64.

Итого:
Код:
MODULE TestThreads2;

IMPORT WinApi, StdLog;

TYPE
    Item = POINTER TO RECORD
  time: LONGINT;
  thread, num: INTEGER;
  next: Item;
  ballast: ARRAY 100000 OF BYTE;
    END;

CONST
    MaxItemsCount = 1000;
    
VAR
    CriticalSection: WinApi.RTL_CRITICAL_SECTION;
    ItemListFront, ItemListBack: Item;
    items_count: INTEGER;
    t0: LONGINT;
    
PROCEDURE Action(IpParameter: INTEGER): INTEGER;
VAR x: Item; num: INTEGER;
BEGIN
    num := 0;
    WHILE items_count < MaxItemsCount DO
  WinApi.EnterCriticalSection(CriticalSection);
  IF items_count < MaxItemsCount THEN
      NEW(x); 
      IF x # NIL THEN
    INC(items_count); INC(num);
    x.time := WinApi.GetTickCount() - t0; 
    x.thread := IpParameter;
    x.num := num;
    IF ItemListBack # NIL THEN ItemListBack.next := x END;
    ItemListBack := x;
    IF ItemListFront = NIL THEN ItemListFront := ItemListBack END
      END
  END;
  WinApi.LeaveCriticalSection(CriticalSection);
  WinApi.Sleep(100)
    END;
    WinApi.ExitThread(0); RETURN 0
END Action;

PROCEDURE Main*;
CONST N = 1000;
VAR 
    a, i: INTEGER; 
    h: ARRAY N OF WinApi.HANDLE; 
    t: ARRAY N OF INTEGER;
    x: Item;
BEGIN
    items_count := 0; ItemListFront := NIL; ItemListBack := NIL;
    WinApi.InitializeCriticalSection(CriticalSection);
    t0 := WinApi.GetTickCount();
    FOR i := 0 TO N-1 DO h[i] := WinApi.CreateThread(NIL, 0, Action, i+1, {}, t[i]) END;
    FOR i := 0 TO N-1 DO a := WinApi.WaitForSingleObject(h[i], WinApi.INFINITE) END;
    FOR i := 0 TO N-1 DO a := WinApi.CloseHandle(h[i]) END;
    WinApi.DeleteCriticalSection(CriticalSection);
    StdLog.Ln; StdLog.String('Items count = '); StdLog.Int(items_count); StdLog.Ln;
    x := ItemListFront; i := 1;
    WHILE x # NIL DO
  StdLog.Int(i); StdLog.String(")"); 
  StdLog.Int(x.thread); StdLog.Int(x.num); StdLog.Int(x.time); StdLog.Ln;
  INC(i); x := x.next
    END;
    ItemListFront := NIL; ItemListBack := NIL;
END Main;

END TestThreads2.
Ответить с цитированием
  (#10 (permalink)) Старый
Phinc Phinc вне форума
Member
 
Сообщений: 32
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 15.10.2004
По умолчанию 14.01.2005, 16:01

Необходимо закрыть поток по завершению работы программы. Все время работы программы поток выполняется.

Код:
PROCEDURE SecondThread*(Parameter: WinApi.PtrVoid): INTEGER;
BEGIN
    WHILE ~property DO
  WinApi.Sleep(600);
  Init_critical:=TRUE;
  Views.Update(v, Views.keepFrames);
    END;
    WinApi.ExitThread(0);
    RETURN 0;
END SecondThread;
CLOSE
    property:=TRUE;
Если вставить ExitThread в раздел CLOSE, то программа некорректно завершается. Но и таким образом функция ExitThread никогда не вызовется. Необходимо ее еще раз вызвать либо реализовать другим образом. В голову ничего не приходит путного.
Ответить с цитированием
  (#11 (permalink)) Старый
S.Yu.Gubanov S.Yu.Gubanov вне форума
Member
 
Сообщений: 587
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 03.12.2002
По умолчанию 14.01.2005, 16:36

Цитата:
Originally posted by Phinc
[b]Необходимо закрыть поток по завершению работы программы...
Я в Delphi, например, делал так: Когда пользователь нажимает на кнопку завершения работы, то программа гасит все контролы (так что нажать больше ни на что нельзя) и выводит сообщение 'Пожалуйста подождите пока программа завершает свою работу.', в это время программа ждала пока все потоки завершаться, и после этого завершалась сама.
Ответить с цитированием
  (#12 (permalink)) Старый
Ketmar Ketmar вне форума
Member
 
Сообщений: 14
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 22.02.2005
По умолчанию 22.02.2005, 06:59

есть подозрение, что GC должен терять память или собирать лишнее при нескольких потоках. он не сканирует стеки потоков (кроме главного), что ведеёт к неизбежным потерям. проверено по исходникам, тест писать лень %-)

проще говоря: ежели поток создает что-то "внутри себя", и на это "что-то" нет ссылок в главном потоке -- это потеряется. кажется, будет просто выкинуто нафиг при следующей сборке.

надо править GC. несколько строк -- и куча радости.

к тому же: сборка мусора ДОЛЖНА быть атомарным процессом (если использовать тот GC, который есть сейчас), иначе можем поиметь чудные сбои по "непонятным причинам".

все подробности -- в исходниках ЧЯ и анализе их %-))
если мне повезёт -- то через пару месяцев у меня будет возможность начать "дотачивать" ЧЯ до многопоточности, тогда, возможно, и напишу больше...
Ответить с цитированием
Ads
  (#13 (permalink)) Старый
Ketmar Ketmar вне форума
Member
 
Сообщений: 14
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 22.02.2005
По умолчанию 22.02.2005, 06:59

есть подозрение, что GC должен терять память или собирать лишнее при нескольких потоках. он не сканирует стеки потоков (кроме главного), что ведеёт к неизбежным потерям. проверено по исходникам, тест писать лень %-)

проще говоря: ежели поток создает что-то "внутри себя", и на это "что-то" нет ссылок в главном потоке -- это потеряется. кажется, будет просто выкинуто нафиг при следующей сборке.

надо править GC. несколько строк -- и куча радости.

к тому же: сборка мусора ДОЛЖНА быть атомарным процессом (если использовать тот GC, который есть сейчас), иначе можем поиметь чудные сбои по "непонятным причинам".

все подробности -- в исходниках ЧЯ и анализе их %-))
если мне повезёт -- то через пару месяцев у меня будет возможность начать "дотачивать" ЧЯ до многопоточности, тогда, возможно, и напишу больше...
Ответить с цитированием
Ads
Ответ

Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Trackbacks are Вкл.
Pingbacks are Вкл.
Refbacks are Выкл.


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Thread stopped что это значит l&#39;Question WinAPI 0 14.12.2009 00:44
Exception in thread как исправить ошибку X-Cite_Forever Java 2 21.11.2008 15:42
Управление элементами одного модуля из другого модуля Roma312 C++ Builder 17 25.08.2008 08:44
Как проанализировать код на thread-safe Гуменюк Роман Delphi 5 20.07.2007 17:08
подключение модуля из модуля kost Pascal 1 22.02.2007 02:06
Thread.Join как убить процесс Drey^the^first .NET 4 24.11.2006 14:00
Как работать с Thread BaRaDeD C++ Builder 3 13.04.2006 23:50
DataGrid & Thread обновление функции Eugene_ .NET 1 30.03.2006 13:03
Создание два thread вместе Rider C++ Builder 2 01.02.2006 00:38
Создание приложения с использованием потоков THREAD lord Visual C++ 2 03.10.2005 09:50
Где найти книгу по Thread DarkShade C++ Builder 9 25.11.2004 18:43
Как загрузить Socket в Thread kamyu Delphi 1 31.03.2004 10:14



Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
Нardforum.ru - компьютерный форум и программирование, форум программистов