Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > Общие вопросы .NET
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 27.12.2009, 14:49   #1
neon2k
 
Регистрация: 07.01.2009
Сообщений: 8
Вопрос Синхронизация потоков в C#. Методы то какие?!

Доброго времени суток, ребят)
Дело вот в чем.
Делал лабу по программированию, было задание для работы с потоками, а именно:
Цитата:
Написать программу, создающую три потока. Каждый поток выполняет какие-то вычисления. При чём второму потоку на каком-то этапе вычисления необходимы результаты работы первого потока, а третьему результаты работы второго потока. Создавать потоки необходимо в таком порядке: третий, второй, первый. Результат расчёта каждый поток должен отобразить на экране и идентифицировать себя;
Сделал я эту лабу. Вроде работает, но вот в чем проблема. Препод сказал, что нужно ЯВНО использовать какой-либо метод синхронизации. А у меня все, по-ходу, опирается на плечи компилятора, который сам решает, какой метод юзать.
Потому дал мне задание: либо разобраться и капнуть в библиотеки шарпа, и показать ему сами API команды, которые интерпретируются потом в шарповский синтаксис (lock , к примеру), либо в программе использовать не готовые методы шарпа, а ЯВНО юзать API команды с использованием какого-либо метода.

Вот код моей программы:
Program.cs:
Код:
using System;
using System.Threading;

namespace ConsoleApplication13
{
    class Program
    {
        public static double data;

        static void Main()
        {
            T3 thr3 = new T3();
            thr3.thread3.Join();

            Console.ReadKey();
        }
    }
}
Thread1.cs:
Код:
using System;
using System.Threading;
using System.Runtime.CompilerServices;

namespace ConsoleApplication13
{
    class T1 
    {
        private Int64 a;
        public Thread thread1;

        public T1()
        {
            thread1 = new Thread(new ThreadStart(this.run));
            thread1.Name = "Поток 1";
            thread1.Priority = ThreadPriority.Highest;
            thread1.Start();
        }

        public void run()
        {
            lock (this) Console.WriteLine("Поток 1 стартовал");
            InputData();
            lock (this) Program.data = a;
            lock (this) Console.WriteLine("Поток 1 завершен! Значение равно:" + Program.data.ToString());
        }

        [MethodImplAttribute(MethodImplOptions.Synchronized)]
        public void InputData()
        {
            Console.WriteLine("Введите A");
            a = int.Parse(Console.ReadLine());
        }
    }
}
Thread2.cs:
Код:
using System;
using System.Threading;
using System.Runtime.CompilerServices;

namespace ConsoleApplication13
{
    class T2 
    {
        private Int64 b;
        public Thread thread2;

        public T2()
        {
            thread2 = new Thread(new ThreadStart(this.run));
            thread2.Name = "Поток 2";
            thread2.Priority = ThreadPriority.Normal;
            thread2.Start();
        }

        public void run()
        {
            lock (this) Console.WriteLine("Поток 2 стартовал");
            InputData();
            
            T1 thr1 = new T1();
            thr1.thread1.Join();
            lock (this) Program.data = Math.Sqrt(Program.data * b);
            lock (this) Console.WriteLine("Поток 2 завершен! Значение равно:" + Program.data);
        }

        [MethodImplAttribute(MethodImplOptions.Synchronized)]
        public void InputData()
        {
            Console.WriteLine("Введите B");
            b = int.Parse(Console.ReadLine());
        }
    }
}
Thread3.cs:
Код:
using System;
using System.Threading;
using System.Runtime.CompilerServices;

namespace ConsoleApplication13
{
    class T3 
    {
        private Int64 c;
        public Thread thread3;

        public T3()
        {
            thread3 = new Thread(new ThreadStart(this.run));
            thread3.Name = "Поток 3";
            thread3.Priority = ThreadPriority.Lowest;
            thread3.Start();
        }

        public void run()
        {
            lock (this) Console.WriteLine("Поток 3 стартовал");
            InputData();
            T2 thr2 = new T2();
            thr2.thread2.Join();
            lock (this) Program.data = Program.data * c;
            lock (this) Console.WriteLine("Поток 3 завершен! Значение равно:" + Program.data);
        }

        [MethodImplAttribute(MethodImplOptions.Synchronized)]
        public void InputData()
        {
            Console.WriteLine("Введите C");
            c = int.Parse(Console.ReadLine());
        }
    }
}
Собственно, кто поможет разобраться?

А то спрашивает: "А какой метод синхронизации используете?". А я и сам не знаю А если говорю, допустим, "Критические секции", он говорит: "а покажите мне, где тут CRITICAL_SECTION".

Последний раз редактировалось neon2k; 27.12.2009 в 23:51.
neon2k вне форума Ответить с цитированием
Старый 27.12.2009, 23:52   #2
neon2k
 
Регистрация: 07.01.2009
Сообщений: 8
По умолчанию

Я надеюсь суть ясна? Просто надо до среды...
neon2k вне форума Ответить с цитированием
Старый 28.12.2009, 17:13   #3
armivl
Пользователь
 
Регистрация: 26.07.2009
Сообщений: 19
По умолчанию

http://msdn.microsoft.com/ru-ru/libr...g.monitor.aspx
armivl вне форума Ответить с цитированием
Старый 28.12.2009, 17:57   #4
Vitek-pm
Пользователь
 
Регистрация: 17.02.2009
Сообщений: 56
По умолчанию

Вот нашел пример работы с мьютексом:
Код:
// This example shows how a Mutex is used to synchronize access
// to a protected resource. Unlike Monitor, Mutex can be used with
// WaitHandle.WaitAll and WaitAny, and can be passed across
// AppDomain boundaries.

using System;
using System.Threading;

class Test
{
    // Create a new Mutex. The creating thread does not own the
    // Mutex.
    private static Mutex mut = new Mutex();
    private const int numIterations = 1;
    private const int numThreads = 3;

    static void Main()
    {
        // Create the threads that will use the protected resource.
        for(int i = 0; i < numThreads; i++)
        {
            Thread myThread = new Thread(new ThreadStart(MyThreadProc));
            myThread.Name = String.Format("Thread{0}", i + 1);
            myThread.Start();
        }

        // The main thread exits, but the application continues to
        // run until all foreground threads have exited.
    }

    private static void MyThreadProc()
    {
        for(int i = 0; i < numIterations; i++)
        {
            UseResource();
        }
    }

    // This method represents a resource that must be synchronized
    // so that only one thread at a time can enter.
    private static void UseResource()
    {
        // Wait until it is safe to enter.
        mut.WaitOne();

        Console.WriteLine("{0} has entered the protected area", 
            Thread.CurrentThread.Name);

        // Place code to access non-reentrant resources here.

        // Simulate some work.
        Thread.Sleep(500);

        Console.WriteLine("{0} is leaving the protected area\r\n", 
            Thread.CurrentThread.Name);

        // Release the Mutex.
        mut.ReleaseMutex();
    }
}
Vitek-pm вне форума Ответить с цитированием
Старый 28.12.2009, 19:03   #5
armivl
Пользователь
 
Регистрация: 26.07.2009
Сообщений: 19
По умолчанию

Mutex очень тяжеловесный, он использует ядро системы для реализации синхронизации между потоками. Поэтому его применяют если необходима синхронизация в различных процессах. Если же тебе достаточно синхронизировать доступ внутри одного процесса используй объект System.Threading.Monitor он же самый lock.
armivl вне форума Ответить с цитированием
Старый 28.12.2009, 21:29   #6
neon2k
 
Регистрация: 07.01.2009
Сообщений: 8
По умолчанию

Я то lock использовал
НО какой это из трех методов?
Ну не мьютекс, понятно)))
Семафоры? События? Критические секции? Я запутался уже)
neon2k вне форума Ответить с цитированием
Старый 28.12.2009, 23:30   #7
armivl
Пользователь
 
Регистрация: 26.07.2009
Сообщений: 19
По умолчанию

class AnyClass
{
public void IsMethodCallManyThread()-этот метод потенциально может быть вызван из различных потоков в один момент времени
{
lock(this)- это начало критической секции (какой - либо поток, который входит в эту критическую секцию захватывает блокировку предоставленную данным объектом "this" все остальные потоки становятся в очередь ожидая когда поток владеющий блокировкой отдаст ее следующему потоку
{
выполнение каких-либо действий над данными гаранитированно только одним потоком в момент времени

} -конец критической секции (поток отдает блокировку потоку ожидающему в очереди
}
}

использование оператора lock
это тоже самое, что и использование класса Monitor
с единственным различием, что в этом режиме доступны
некоторые дополнительные возможности.
class AnyClass
{
public void IsMethodCallManyThread()-этот метод потенциально может быть вызван из различных потоков в один момент времени
{
Monitor.Enter(this)- это начало критической секции
try
{
выполнение каких-либо действий над данными гаранитированно только одним потоком в момент времени
}
finally
{
Monitor.Exit(this);-выход из критической секции
}
}
armivl вне форума Ответить с цитированием
Старый 30.12.2009, 18:41   #8
neon2k
 
Регистрация: 07.01.2009
Сообщений: 8
По умолчанию

Спасибо.
Теперь такой вопрос.
Как в C# использовать API функции ОС?
Т.е. напрямую использовать API-функции работы с потоками.
Не получается у меня объявить их
neon2k вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Работа с потоками den49 Помощь студентам 0 06.10.2009 14:52
Работа с потоками Нюська Общие вопросы Delphi 3 27.05.2009 00:52
Работа с потоками Neymexa Общие вопросы .NET 16 23.04.2009 17:42
работа с потоками Alex_Pro Общие вопросы .NET 1 01.07.2008 07:25
C++, работа с потоками mat90x Помощь студентам 20 15.05.2008 22:20