Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/9: Рейтинг темы: голосов - 9, средняя оценка - 4.89
41 / 40 / 23
Регистрация: 10.03.2012
Сообщений: 374

Синхронизация нескольких потоков

09.06.2014, 14:42. Показов 1965. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте! Имеются несколько потоков, в каждом из которых выполняются два и более методов. Необходимо синхронизировать их. Пробовал использовать класс barrier, но результат не тот:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
Barrier barrier = new Barrier(2); // 2 = #threads participating.
            bool complete = false;
            TaskFactory factory = Task.Factory;
 
            // Start tasks
            Task task_1 = factory.StartNew(() =>
            {
                process_1.Server("1 and 2");
                barrier.SignalAndWait(); // Wait for task 2 to catch up.
                barrier.SignalAndWait(); // Wait for task 2 to print "2" and set complete = true.
 
                if (complete)
                {
                    process_1.Server("1 and 3");
                }
            });
            Task task_6 = factory.StartNew(() =>
            {
                process_6.Server("6 and 4");
                process_6.Server("6 and 3");
            });
            Task task_2 = factory.StartNew(() =>
            {
                barrier.SignalAndWait(); // Wait for task 1 to print "1".
                process_2.Client("1 and 2");
                complete = true;
                barrier.SignalAndWait(); // Wait for task 1 to read complete as true.
 
                process_2.Server("2 and 5");
                process_2.Server("2 and 3");
            });
            Task task_4 = factory.StartNew(() =>
            {
                process_4.Client("6 and 4");
                process_4.Server("4 and 7");
                process_4.Server("4 and 3");
            });
            Task task_5 = factory.StartNew(() =>
            {
                process_5.Client("2 and 5");
                process_5.Server("5 and 3");
            });
            Task task_7 = factory.StartNew(() =>
            {
                process_7.Client("4 and 7");
                process_7.Server("7 and 3");
            });
            Task task_3 = factory.StartNew(() =>
            {
                process_3.Client("1 and 3");
                process_3.Client("2 and 3");
                process_3.Client("4 and 3");
                process_3.Client("5 and 3");
                process_3.Client("6 and 3");
                process_3.Client("7 and 3");
            });
 
            task_3.Wait();
Мне нужно обеспечить последовательный вызов методов из разных потоков: сначала
C#
1
process_1.Server("1 and 2");
, а потом
C#
1
process_2.Client("1 and 2");
. То есть метод Client всегда должен выполняться после метода Server с тем же параметром. Вот все имеющиеся зависимости: {process_1.Server("1 and 2"); process_2.Client("1 and 2");}, {process_2.Server("2 and 5"); process_5.Client("2 and 5");}, {process_6.Server("6 and 4"); process_4.Client("6 and 4");}, {process_4.Server("4 and 7"); process_7.Client("4 and 7");}, {process_1.Server("1 and 3"); process_3.Client("1 and 3");}, {process_2.Server("2 and 3"); process_3.Client("2 and 3");}, {process_4.Server("4 and 3"); process_3.Client("4 and 3");}, {process_5.Server("5 and 3"); process_3.Client("5 and 3");}, {process_6.Server("6 and 3"); process_3.Client("6 and 3");}, {process_7.Server("7 and 3"); process_3.Client("7 and 3");}.
Методы, заключенные в {...} должны обязательно выполняться в указанной последовательности. Но сами эти скобки могут запускаться в любой последовательности. То есть возможно сначала выполнить {process_6.Server("6 and 3"); process_3.Client("6 and 3");}, а потом {process_7.Server("7 and 3"); process_3.Client("7 and 3");}. Но и наоборот тоже будет правильно: {process_7.Server("7 and 3"); process_3.Client("7 and 3");}, {process_6.Server("6 and 3"); process_3.Client("6 and 3");}.
Подскажите, какие методы синхронизации нужно использовать? Заранее спасибо!
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
09.06.2014, 14:42
Ответы с готовыми решениями:

Синхронизация потоков на элементарном уровне (переключение потоков)
в общем разбираюсь с потоками, на сколько понял мне нужен lock Вот имеется просто пример public void RunAdd() ...

Синхронизация потоков: проблема гонки потоков
Есть проблема в синхронизации потоков, которую я не знаю, как решить. Точнее у меня получается типичная гонка потоков. Есть функция,...

Синхронизация потоков
Есть ли возможность в C# сделать часть кода потока защищенным от прерывания другими потоками. Lock не подходит, т.к. потоки не используют...

6
192 / 199 / 82
Регистрация: 11.04.2013
Сообщений: 1,086
09.06.2014, 16:28
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
List<Task> ListTask = new List<Task>();
 
            Task task_1 = new Task(() =>
            {
                process_1.Server("1 and 2");
                //.....
            });
 
            Task task_2 = new Task(() =>
            {
                process_2.Client("1 and 2");
                //....
             });
            ListTask.Add(task_1);
            ListTask.Add(task_2);
 
            ListTask[0].Start();
            Task.WaitAny(ListTask[0]);
            ListTask[1].Start();
0
41 / 40 / 23
Регистрация: 10.03.2012
Сообщений: 374
09.06.2014, 18:20  [ТС]
EVG-1980, нет так не работает. Получается потоки блокируются, потому что у меня вот такие методы:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public void Server(object pipeName)
        {
            // Create a name pipe
            using (NamedPipeServerStream pipeStream = new NamedPipeServerStream(pipeName.ToString()))
            {
                // Wait for a connection
                pipeStream.WaitForConnection();
 
                using (StreamWriter sw = new StreamWriter(pipeStream))
                {
                    sw.AutoFlush = true;
                    sw.WriteLine(message);
                }
                //pipeStream.Close();
                Console.Write("Communication between processes " + pipeName.ToString());
            }
        }
 
        public void Client(object pipeName)
        {
            using (NamedPipeClientStream pipeStream = new NamedPipeClientStream(pipeName.ToString()))
            {
                // The connect function will indefinately wait for the pipe to become available
                // If that is not acceptable specify a maximum waiting time (in ms)
                pipeStream.Connect();
 
                using (StreamReader sr = new StreamReader(pipeStream))
                {
                    // We read a line from the pipe and print it together with the current time
                    message += sr.ReadLine();
                }
                //pipeStream.Connect();
                Console.WriteLine(": client received message.\n");
            }
        }
Может можно как-то прервать выполнение потока после выполнения одного из его методов, а потом снова возобновить?

Добавлено через 16 минут
Получается, если создать эти потоки в цикле, выходит так, что могут создаться два Server подряд и выводятся сообщения "Communication between processes 1 and 2Communication between processes 1 and 3". А за каждым сервером должен следовать соответствующий ему клиент, который в другом потоке. Тогда выводится на экран: "Communication between processes 1 and 3: client received message."
0
192 / 199 / 82
Регистрация: 11.04.2013
Сообщений: 1,086
09.06.2014, 18:21
RocBoy-D, на одной машине выполняется?
0
41 / 40 / 23
Регистрация: 10.03.2012
Сообщений: 374
09.06.2014, 18:21  [ТС]
EVG-1980, да. Методы для работы с каналами pipeStream.Connect(); сами блокируют выполнение программы до появления клиента, и тут как бы синхронизация и не нужна. То есть передаваемые другому потоку сообщения все равно дойдут. Но нужно синхронизировать вывод этих оповещающих сообщений
0
192 / 199 / 82
Регистрация: 11.04.2013
Сообщений: 1,086
09.06.2014, 18:32
C#
1
2
3
4
5
 Server(object pipeName)
{
//....
Client(object pipeName)
}
попробуй так
0
41 / 40 / 23
Регистрация: 10.03.2012
Сообщений: 374
09.06.2014, 18:36  [ТС]
в смысле? убрать спецификаторы доступа?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
09.06.2014, 18:36
Помогаю со студенческими работами здесь

Синхронизация потоков
Решил попробовать перейти от работы приложения по таймеру к применению потоков - почитал литературы,попробовал закодить несколько простых...

Синхронизация потоков
Есть программа: using System; using System.Diagnostics; using System.Linq; using System.Runtime.ConstrainedExecution; using...

Синхронизация потоков
Не так давно начал заниматься c#.. возникла следующее недопонимание потоков. Программа ищет в цикле случайное число от 0 до 10, цикл...

Синхронизация потоков
Здравствуйте! Есть задача создать два потока в каждом из которых будет бегущая строка(одна справа налево, вторая слева направо). Бегающие...

Синхронизация потоков c#
Всем привет) Решил написать программу, которая в несколько потоков будет выкачивать торрент файлы с трекера, но возникла проблема - в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло. Но на выплатах по больничным это. . .
1С: Контроль уникальности заводского номера
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере документа выдачи шин для спецтехники с табличной частью. Данные берутся из регистра сведений, по которому настроено. . .
Хочу заставить корпорации вкладываться в здоровье сотрудников: делаю мат модель здравосохранения
anaschu 22.03.2026
e7EYtONaj8Y Z4Tv2zpXVVo https:/ / github. com/ shumilovas/ med2. git
1С: Программный отбор элементов справочника по группе
Maks 22.03.2026
Установка программного отбора элементов справочника "Номенклатура" из модуля формы документа. В качестве фильтра для отбора справочника служит группа номенклатуры. Отбор по наименованию группы. . .
Как я обхитрил таблицу Word
Alexander-7 21.03.2026
Когда мигает курсор у внешнего края таблицы, и нам надо перейти на новую строку, а при нажатии Enter создается новый ряд таблицы с ячейками, то мы вместо нервных нажатий Энтеров мы пишем любые буквы. . .
Krabik - рыболовный бот для WoW 3.3.5a
AmbA 21.03.2026
без регистрации и смс. Это не торговля, приложение не содержит рекламы. Выполняет свою непосредственную задачу - автоматизацию рыбалки в WoW - и ничего более. Однако если админы будут против -. . .
1С: Программный отбор элементов справочника по значению перечисления
Maks 21.03.2026
Установка программного отбора элементов справочника "Сотрудники" из модуля формы документа. В качестве фильтра для отбора служит значение перечислений. / / Событие "НачалоВыбора" реквизита на форме. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru