Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.64/11: Рейтинг темы: голосов - 11, средняя оценка - 4.64
 Аватар для C17H19NO3
218 / 212 / 63
Регистрация: 17.04.2012
Сообщений: 382

Корректировка работы нескольких потоков с одним циклом

17.04.2012, 11:48. Показов 2115. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет. Ребята, нужна ваша помощь. Не могу распаралелить поток.

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
namespace potok
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        delegate void listLogPotokDelegate(string text);
 
        private void listLogPotok(string text)  
        { 
            if (InvokeRequired) 
            { 
                BeginInvoke(new listLogPotokDelegate(listLogPotok), new object[] { text }); return; 
            } 
            else 
            { 
                listBox1.Items.Add(text);
            } 
        }
 
        private void filePotok()
        {
              Random rnd = new Random();
 
                Thread.Sleep(rnd.Next(1000, 10000));
                for (int i = 0; i < 10; i++)
                {
                      listLogPotok(Thread.CurrentThread.Name + ": " + i.ToString());
                }
 
                Thread.Sleep(rnd.Next(1000, 10000));
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            Thread[] th = new Thread[modems.Count];  // modems.Count - массив модемов
            for (int i = 0; i < modems.Count; i++)
            {
                th[i] = new Thread(filePotok);
                th[i].IsBackground = true;
                Thread.Sleep(1000);
                th[i].Start();
            }
        }
    
    }
}

В чем собственно состоит проблема.
Сейчас каждый поток выводит числа от 0 до 9, а
мне нужно чтоб выводило следующие записи

th0 = 0;
th1 = 1;
th3 = 2;
th0 = 4;
th2 = 3;
th0 = 6;
th2 = 5; ......

то есть заданное количество потоков вместе работали с одним цыклом. Один поток выводит одно число, второй второе, третий четвертее, четвертый третее и т.д.

Скажу наперед, что явно распределить на сигменты не получить потому, что количестве запичей в цыкле будет менятся от 1 до 5000.

Если кому то интересно - то это программа обзвона обенентов под 5 модемов. Каждый модем - отдельныя ветка. То есть каждый модем берет телефон с массива и звонит на него. Такая операция должна паралельно выполнятся под 5 модемов. если я буду явно задавать для каждого модема массив телефнов, то может оказатся, что один можем получит 500 телефнов, второй 30, а все остальные вообще ничего. Поэтому мне и нужно чтоб 5 потоков работали с одной процедурой и работать под 5 потоков с одной процедурой
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
17.04.2012, 11:48
Ответы с готовыми решениями:

Создание нескольких элементов одним циклом
Доброго времени суток всем! Есть задание у меня. Под каждое изображение на странице сайта надо добавить кнопку, которая бы позволяла...

Отображение общего прогресса работы нескольких потоков на одном progressbar
В программе параллельно работают три потока, каждый из которых выполняет одинаковый объем работы, но время выполнения может отличаться. мне...

Вывод результата работы нескольких потоков в Memo - выводится данные только последнего
Всем привет. По нажатию кнопки я создаю определенное количество потоков. mythread := tmythread.create(false); в каждом потоке у...

10
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
17.04.2012, 14:25
Сделайте одну общую коллекцию с телефонами и сколько-то там потоков.
Пусть эти потоки, синхронизируясь, достают по одному элементу из коллекции и звонят на него, пока все элементы не закончатся.

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
ConcurrentQueue<int> queue = new ConcurrentQueue<int>();
void Main()
{
   for (int i = 0; i < 10; i++) queue.Enqueue(i);
   Thread[] threads = new Thread[5];
   for (int i = 0; i < threads.Length; i++)
   {
      threads[i] = new Thread(Dial);
      threads[i].Start();
   }
   foreach (Thread th in threads) th.Join();
   Console.WriteLine("Done");
   Console.ReadKey();
}
 
static void Dial()
{
    int number;
    while (true)
    {
         if (queue.TryDequeue(out number)) Console.WriteLine(number);
         else return;
    }
}
Таким образом избегаете проблемы, когда один мопед уже отзвонился по всем номерам и бьет баклуши, а остальные еще пыхтят, пытаясь дозвониться.
1
 Аватар для C17H19NO3
218 / 212 / 63
Регистрация: 17.04.2012
Сообщений: 382
17.04.2012, 21:48  [ТС]
все бы ничего но в строке

C#
1
if (queue.TryDequeue(out number)) Console.WriteLine(number);
у меня нету компонента "TryDequeue"
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
17.04.2012, 22:02
А в первой строке у вас, получается, есть ConcurrentQueue?
0
 Аватар для C17H19NO3
218 / 212 / 63
Регистрация: 17.04.2012
Сообщений: 382
18.04.2012, 09:16  [ТС]
да, этой тоже нету. Все написано под Framework 3.5
твой код под 4-ый. Пасиб, в режиме теста все работает, попробую отточить код под 4-й фрейм.
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
18.04.2012, 12:03
Под 3.5 тоже можно написать, но придется синхронизировать очередь вручную:
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
static Queue<int> queue = new Queue<int>();
static object queueLock = new object();
 
static void Main()
{
    for (int i = 0; i < 10; i++) queue.Enqueue(i);
    Thread[] threads = new Thread[5];
    for (int i = 0; i < threads.Length; i++)
    {
        threads[i] = new Thread(Dial);
        threads[i].Start();
    }
    foreach (Thread th in threads) th.Join();
    Console.WriteLine("Done");
    Console.ReadKey();
}
 
static void Dial()
{
    int number;
    while (true)
    {
        lock (queueLock)
        {
            if (queue.Count > 0)
                number = queue.Dequeue();
            else return;
        }
        Console.WriteLine(number);
    }
}
1
 Аватар для C17H19NO3
218 / 212 / 63
Регистрация: 17.04.2012
Сообщений: 382
18.04.2012, 13:08  [ТС]
kolorotur, пасиб виручил.
ща разберусь с кодом. потому что с очередями еще не работал.

Может кому-то пригодится, код работы 5-и потоков с одним масивом.

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
 
namespace fiveThreads
{
    class Program
    {
        const int N = 20;
        static int[] array  = new int[N];
       static int  PtrToArray = 0;
      static object ttt = new object();
 
      static void InitializeArray()
      {
          for (int i = 0; i < N; i++)
          {
              array[i] = i;
          }
      }
 
        static void Main(string[] args)
        {
            InitializeArray();
 
 
            for (int i = 0; i < 5; i++)
            {
                Thread th = new Thread(new ThreadStart(proc));
                th.Start();
            }
            Console.ReadLine();
        }
 
 
       static void proc()
        {
           Random rnd = new Random();
            while (PtrToArray < N)
            {
                int curVal;
                lock (ttt)
                {
                    curVal = array[PtrToArray++];
                }
                    Console.WriteLine("Potok {0}: chislo {1}", Thread.CurrentThread.ManagedThreadId, curVal);
                Thread.Sleep(rnd.Next(2000));
                
            }
        }
                
    }
}
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
18.04.2012, 13:16
У вас не синхронизирован доступ к PtrToArray во время проверки.
Может возникнуть ситуация с выходом за пределы массива.
0
 Аватар для C17H19NO3
218 / 212 / 63
Регистрация: 17.04.2012
Сообщений: 382
19.04.2012, 14:44  [ТС]
так он же лочится при при каждом новом переходе:

C#
1
2
3
4
 lock (ttt)
    {
       curVal = array[PtrToArray++];
    }
я не говорю, что вы не правы, просто не могу понять почему такое может произойти.
не могу смоделировать такую ситуацию, когда он может это сделать.
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
19.04.2012, 15:24
Он лочится, но только при инкременте, а при проверке - нет.
Ситуацию смоделировать очень легко:
Итак, у нас есть следующий цикл:
C#
1
2
3
4
5
6
7
8
9
10
11
            while (PtrToArray < N)
            {
                int curVal;
                lock (ttt)
                {
                    curVal = array[PtrToArray++];
                }
                    Console.WriteLine("Potok {0}: chislo {1}", Thread.CurrentThread.ManagedThreadId, curVal);
                Thread.Sleep(rnd.Next(2000));
                
            }
Этот цикл выполняется одновременно, допустим, из двух потоков.
Предположим, что происходит обход массива из десяти элементов и на данный момент значение PtrToArray = 9, N = 10.
Начинаем отслеживание:
1. Первый поток делает проверку. Проверка проходит.
2. Второй поток делает проверку. Проверка проходит.
3. Первый поток создает переменную curVal.
4. Второй поток создает переменную curVal.
5. Первый поток заходит в критическую зону.
6. Второй поток пытается зайти в критическую зону и замораживается, т.к. в ней уже первый поток.
7. Первый поток достает элемент под индексом 9, присваивает его переменной curVal и увеличивает значение PtrToArray до 10-и.
8. Первый поток выходит из критической зоны и выводит сообщение.
9. Второй поток заходит в критическую зону.
10. Второй поток пытается достать элемент под индексом 10 (он ведь уже раньше прошел проверку и "предполагает", что PtrToArray все еще < N) и чпок - вылетает IndexOutOfRangeException.

Исправить можно, делая проверку и присваивание значения элементу в критической зоне:
C#
1
2
3
4
5
6
7
8
9
10
11
12
            while (true)
            {
                int curVal;
                lock (ttt)
                {
                    if (PtrToArray < N) curVal = array[PtrToArray++];
                    else return;
                }
                    Console.WriteLine("Potok {0}: chislo {1}", Thread.CurrentThread.ManagedThreadId, curVal);
                Thread.Sleep(rnd.Next(2000));
                
            }
1
 Аватар для C17H19NO3
218 / 212 / 63
Регистрация: 17.04.2012
Сообщений: 382
19.04.2012, 23:17  [ТС]
Добавлено через 2 минуты
все, въехал.! спасибо, вам, за розъяснения.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
19.04.2012, 23:17
Помогаю со студенческими работами здесь

Сделать с одним циклом
Дана программа: CLS PRINT “ Ряд чётных чисел:” PRINT “ Пошаговая сумма чётных чисел:” FOR i = 1 TO 10 STEP 2 PRINT i; ...

Программа с одним циклом
CLS DIM A(5) PRINT “ Создание массива” FOR i = 1 TO 5 INPUT “ Ввести числа: “, A( i ) NEXT i PRINT “ “ FOR i =...

Замедление работы потоков если запущено несколько потоков
Есть отдельный поток который движет красным квадратом. Он каждую миллисекунду меняет положение квадрата на пиксель. Есть другой поток, он...

Создание потоков циклом
У меня возник вопрос. Надо сделать программу в которой каждая математическая функция создаётся в своём потоке. using System; using...

Заполнить матрицу одним циклом
Нужно заполнить матрицу заданного размера в одном цикле (не использовать вложенные for). Я нарисовал блок-схему (вложение) и написал...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru