1 / 1 / 3
Регистрация: 27.11.2012
Сообщений: 146
1

Многопоточное программирование по Шилдту: разобрать код

03.01.2013, 19:55. Показов 1875. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Друзья, у меня вопрос от новичка. Читаю книгу Шилдта и вот дошёл до главы многопоточного программирования. В книге приведён следующий пример, демонстрирующий работу методов lock, Wait, Pulse:

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// Использование методов Wait() и Pulse() для создания
// тикающих часов.
 
using System;
using System.Threading;
 
class TickTock {
 
    public void tick(bool running) {
        lock(this) {
            if(!running) { // Останов часов.
                Monitor.Pulse(this);    // Уведомление любых
                                            // ожидающих потоков,
                return;
            }
            Console.Write("тик ");
            Monitor.Pulse(this);    // Разрешает выполнение
                                    // метода tock().
            Monitor.Wait(this);     // Ожидаем завершения
                                    // метода tock().
        }
    }
    public void tock(bool running) {
        lock(this) {
            if(!running) {          // Останов часов.
                Monitor.Pulse(this);    // Уведомление любых
                                        // ожидающих потоков,
                return;
            }
            Console.WriteLine("так");
            Monitor.Pulse(this);    // Разрешает выполнение
                                    // метода tick().
            Monitor.Wait(this); // Ожидаем завершения
                                // метода tick().
        }
    }
 
    class MyThread
    {
 
        public Thread thrd;
        TickTock ttOb;
        // Создаем новый поток.
        public MyThread(string name, TickTock tt)
        {
            thrd = new Thread(new ThreadStart(this.run));
            ttOb = tt;
            thrd.Name = name;
            thrd.Start();
        }
 
        // Начинаем выполнение нового потока,
        void run()
        {
            if (thrd.Name == "тик")
            {
                for (int i = 0; i < 5; i++) ttOb.tick(true);
                ttOb.tick(false);
            }
 
            else
            {
                for (int i = 0; i < 5; i++) ttOb.tock(true);
                ttOb.tock(false);
            }
        }
    }
        class TickingClock
        {
 
            public static void Main()
            {
 
                TickTock tt = new TickTock();
 
                MyThread mtl = new MyThread("тик", tt);
 
                MyThread mt2 = new MyThread("так", tt);
 
                mtl.thrd.Join();
 
                mt2.thrd.Join();
 
                Console.WriteLine("Часы остановлены");
 
                Console.ReadLine();
            }
        }
    }
Возникла одна проблема понимания того, как этот код работает.
Результат выполнения кода такой
тик так
тик так
тик так
тик так
тик так
Часы остановлены

Вопрос в следующем: в этом коде создаётся два потока. В программе внутри одного класса, в разных методах есть участок кода, заключенный в инструкцию
C#
1
lock(this){}
Первый поток начинает выполнение кода одного из этих участков. Означает ли это то, что кроме блокирования этого участка блокируется для другого потока и код в другом методе? Как я полагал, блокировка происходит только для того участка, где происходит выполнение программы первым потоком. Но судя по результатам выполнения программы, блокируется оба участка. Сначала хотелось бы выяснить, я правильно понял или нет. И как на самом деле обстоят дела в этом коде и в общем случае.
Спасибо!
После Ваших ответов, думаю возникнут дополнительные вопросы, которые я задам.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.01.2013, 19:55
Ответы с готовыми решениями:

Многопоточность (по Шилдту) - разобрать строку кода
Здравствуйте! У меня вопрос: в чем смысл строки кода if(currentName != Thrd.Name) в методе Run()...

Криптография, многопоточное программирование, сетевое программирование
Не знаю, с чего начать, подскажите: В этом задании необходимо реализовать клиент-серверное...

Многопоточное программирование
Здравствуйте, читал литературу по C# с целью разобраться как сделать многопоточную программу, но...

Многопоточное программирование
Как я понимаю, есть много библиотек, с помощью которых мы можем использовать многопоточность. Чем...

5
713 / 680 / 126
Регистрация: 30.03.2012
Сообщений: 1,124
03.01.2013, 22:28 2
насколько я понимаю
lock блокирует не код, а объект, соответственно когда код в другом потоке пытается заблокировать тот же объект и обнаруживает, что он заблокирован другим потоком - ожидает разрешения его использовать
1
Темная сторона .Net
592 / 489 / 39
Регистрация: 21.07.2012
Сообщений: 1,668
03.01.2013, 22:32 3
dima-dima, Проблема с использованием данных несколькими потоками очень существенна.
Это один из способов ее решение. Дать возможность только одному потоку работать с данными в данный момент.

Там дальше идет речь о транзакциях и проблемах связанных с необдуманным использованием доступа к данным.

p.s.
The lock keyword marks a statement block as a critical section by obtaining the mutual-exclusion lock for a given object, executing a statement, and then releasing the lock.
1
1 / 1 / 3
Регистрация: 27.11.2012
Сообщений: 146
04.01.2013, 07:19  [ТС] 4
Поправьте, если я не верно понял:
Если в инструкцию lock заключить несколько участков кода (всё в рамках одного объекта), то в момент выполнения одним из потоков любого из участков блокируется и остальные.
Если в инструкцию lock заключить несколько участков кода, (в рамках нескольких объектов), то в момент выполнение одним из потоков любого из участков блокируется и остальные, кроме тех, в параметрах lock которых указаны другие объекты.
0
Master of Orion
Эксперт .NET
6094 / 4950 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
04.01.2013, 15:38 5
dima-dima, http://ru.wikipedia.org/wiki/%... 0%B8%D1%8F
параметро lock блокирует доступ к объекту блокировки. Если у вас есть 2 блока lock(this), то при достижении одним потоков любого из этих блоков, никакой другой поток не сможет продолжить выполнение. Если же у вас 2 блока lock(obj1) и lock(obj2) то при достижении потоком lock(obj1) будут блокироваться только потоки, которые будут посягать на этот объкт, то есть если следующий поток достигает lock(obj2), то он спокойно заходит в критическую секцию, так как занимаются различные критические ресурсы.
1
1 / 1 / 3
Регистрация: 27.11.2012
Сообщений: 146
04.01.2013, 16:14  [ТС] 6
Спасибо, друзья. Пока вопросов нет.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.01.2013, 16:14
Помогаю со студенческими работами здесь

Многопоточное программирование
#include &quot;stdafx.h&quot; #include &lt;Windows.h&gt; #include &lt;stdio.h&gt; #define n 5000 long g_counter=0; ...

Многопоточное программирование
Добрый день! Можете посоветовать кнгиги по многопоточному программированию на C++, не привязанные...

Многопоточное программирование на С++
Здравствуйте, уважаемые форумчане ! Хотелось бы обратиться за помощью ! Передо мной стоит задача...

Многопоточное программирование
Добрый день! Мне нужно реализовать следующую задачку. Есть текстовый файл с матрицей. Нужно,...


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru