Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > есть ли аналог Monitor(C#)


Автор: Ch0bits 29.4.2005, 21:38
Я сейчас некоторые свои программы перевожу на Delphi. И вот возник вопрос.

Допустим у меня есть несколько нитей(thread), они обращаются к одному ресурсу(объекту).
Как мне заблокировать этот объект пока его обрабатывает какая-либо из нитей.

В C# есть для этого класс Monitor.
Monitor.Enter(object) -> lock object
Monitor.Exit(object) -> unlock object

Автор: Poseidon 29.4.2005, 22:05
function WaitFor: Integer;

Метод WaitFor предназначен для синхронизации и позволяет одному потоку дождаться момента, когда завершится другой поток.

Пример:
Внутри потока FirstThread пишим код
Код
Code := SecondThread.WaitFor;
Поток FirstThread останавливается до момента завершения потока SecondThread. Метод WaitFor возвращает код завершения ожидаемого потока, каторый можно установить свойством ReturnValue (по умолчанию 0)

Можно еще использовать Synchronize(Method: TThreadMethod);

Этот метод относится к секции protected, т. е. может быть вызван только из потомков TThread. Delphi предоставляет программисту метод Synchronize для безопасного вызова методов VCL внутри потоков. Во избежание конфликтных ситуаций, метод synchronize дает гарантию, что к каждому объекту VCL одновременно имеет доступ только один поток. Аргумент, передаваемый в метод Synchronize, — это имя метода, который производит обращение к VCL; вызов Synchronize с этим параметром — это то же, что и вызов самого метода. Такой метод (класса TThreadMethod) не должен иметь никаких параметров и не должен возвращать никаких значений. К примеру, в основной форме приложения нужно предусмотреть функцию.

Опиши по-подробнее в каком контексте тебе это нужно. Тогда будет легче тебе что-то порекомендовать



Автор: Ch0bits 29.4.2005, 22:23
У меня есть несколько матриц. Значения их определяют визуальные компоненты.
В тоже время один поток проверяет правильность ввода, второй прогнозирует будущий ввод пользователя, третий ведёт постобработку для дальнейшего использования.
Если произойдёт одновременный доступ, то все цифры перемешаются и другие алгоритмы в потоках будут работать неправильно.

Может кто-то спросит почему я не сделал всё это без потоков(проще), я лишь скажу что так надо.

Автор: Poseidon 29.4.2005, 23:26
Цитата(Vadim999 @ 29.4.2005, 22:23)
Может кто-то спросит почему я не сделал всё это без потоков(проще), я лишь скажу что так надо.
Я спрошу smile Если все потоки не могут работать одновременно, то их нужно ставить в очередь (по-просту говоря). А очередь потоков - это то же, что и один поток. Вот только если это обязательное условие, то тогда конечно.

Используй WaitFor. Думаю этого хватит для реализации.

Автор: Ch0bits 29.4.2005, 23:44
В Delphi ведь потоки можно задавать только как классы, в у меня они заданы как процедуры.

Если не понятно, то вот пример:
Код

using System;
using System.Threading;

class MainClass
{
    public static void ZZZ()
    {
        int i=0;
        for(;;)
        {
            Thread.Sleep(1000);
            i++;
            Console.WriteLine(i);
        }
    }
    
    public static void Main(string[] args)
    {
        Console.WriteLine("Wait 10 seconds...");
        Thread T=new Thread(new ThreadStart(ZZZ));
        T.IsBackground=true;
        T.Start();
        Thread.Sleep(10*1000);
    }
}


Спасибо за помощь. smile 7 - счастливое число smile

Автор: Poseidon 30.4.2005, 00:22
Млин, говорила мама: "Учи сынок Си". До только сынок этот забил на такую важную вещь! Как видно зря. Но попытаемся понять друг друга.


Цитата(Vadim999 @ 29.4.2005, 23:44)
В Delphi ведь потоки можно задавать только как классы
Вот это не савсем так. В Delphi есть функции CreateThread и BeginThread каторые создают поток без пременения класа Thread. Пример применения этих функций http://vingrad.ru/DELPHI-DLP-000781

И еще. Что мешает твою процедуру сделать как процедуру Execute класса TThread? Т.е. я об этом
Код
type
  TMyThread = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
  end;

....

procedure TMyThread.Execute;
begin
// наша процедура, каторую нужно запихнуть в поток
end;


И запускать поток тогда вот так
Код
procedure TForm1.Button1Click(Sender: TObject);
var  MyThread: TMyThread;
begin
MyThread := TSearchThread.Create(False);
end;


PS.
Цитата(Vadim999 @ 29.4.2005, 23:44)
Спасибо за помощь.  7 - счастливое число 
smile Ну ничего себе новичок! Ты уже 100 постов как не новичок smile Ну а в общем, всегда пожалуста. Рад знать, что помог (или помогаю) кому-то smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)