Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Использование потоков в c# 
:(
    Опции темы
maxwel6064
Дата 5.3.2014, 18:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 5.3.2014

Репутация: нет
Всего: нет



Добрый день. Нужна ваша помощь с созданием одной программки. Основная часть у меня вроде бы есть, однако не совсем понимаю как сделать следующее:
В общем нужно создать генератор случайных чисел и во время генерации программа должна проверять является ли число первичным и фибоначчи. Программа должна работать по такому принципу: первый поток генерирует числа, второй проверяет является ли число первичным, третий поток проверяет является ли число фибоначчи, а в четвертом потоке должен быть progressbar. Первый поток должен ждать, пока второй и третий поток проверит число и только потом генерировать новое число, т.е. одно сгенерировал число, проверил и дальше генерирует.
В общем я сделал следующий код:
Код:

Код


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using System.Threading;

namespace random_skaiciu_generatorius
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            generate();
        }

    public void generate()
        {
            int numbers = Convert.ToInt32(numericUpDown1.Value);
            int from = Convert.ToInt32(numericUpDown2.Value);
            int to = Convert.ToInt32(numericUpDown3.Value);
            int[] generatedNumbers = new int[numbers];
            int[] fibonacci = new int[numbers];
            fibonacci[0] = 1;
            fibonacci[1] = 1;
            int i=0, j=0;
            int primeNumber;
            progressBar1.Maximum = numbers;
            progressBar1.Minimum = 0;
            Random rnd = new Random();
            Stopwatch stopwatch = new Stopwatch();
           Thread thread1 = new Thread(
                   new ThreadStart(() =>
                   {
                       using (StreamWriter writer =
                           new StreamWriter("rezultatai.txt"))
                       {
                           for (i = 0; i < numbers; i++)
                           {   
                               stopwatch.Start();
                               generatedNumbers[i] = rnd.Next(from, to);
                               writer.WriteLine(generatedNumbers[i]);
                               stopwatch.Stop();
                           }
                       }
                   }));

            Thread thread2 = new Thread(
                new ThreadStart(() =>
                    {
                        for (i = from; i <= to; i++)
                        {
                            for (j = 2; j <= i; j++)
                            {
                                if (i % j == 0)
                                {
                                    break;
                                }
                            }
                            if (i == j)
                            {
                                primeNumber = i;
                                MessageBox.Show(primeNumber.ToString());
                            }
                        }
                    }
            ));
            Thread thread3 = new Thread(
                new ThreadStart(() =>
                    {
                        for (i = from; i <= to; i++)
                        {
                            fibonacci[i] = fibonacci[i - 1] + fibonacci[i - 2];
                            //MessageBox.Show(fibonacci[i].ToString());
                        }
                    }
            ));
            Thread thread4 = new Thread(
            new ThreadStart(() =>
            {
                while (i < numbers)
                {
                    progressBar1.BeginInvoke(
                        new Action(() =>
                        {
                            progressBar1.Value =i;
                        }
                        ));
                }
                
            }
            ));

            thread1.Start();
            thread4.Start();
            thread2.Start();    
            thread3.Join();
            
        }

    }
}


В общем в моем представленном коде программа уже генерирует числа, проверяет на первичность и фибоначчи. Однако вся эта проверка и генерация выполняется сразу для всех чисел. Как можно сделать, чтобы потоки выполнялись бы постепенно, т.е. одно число сгенерировала программа, проверила на первичность и фибоначчи, и только потом чтобы программа начала генерацию нового числа. Интервалы от и до я ввожу с помощью компонента numericupdown, количества чисел также. Надеюсь будет понятен мой код и вы поняли суть вопроса. Заранее большое спасибо за помощь. 
PM MAIL   Вверх
infarch
Дата 6.3.2014, 16:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 526
Регистрация: 13.3.2009

Репутация: 1
Всего: 1



Так как вы ставите задачу, и потоков никаких не надо. Максимум бекграунд воркер заюзать... Было бы правильнее загрузить тред пул задачами генерации, генератор будет скидывать в пул задачу проверки на первичность, оттуда в пул задачу проверки на фибоначи...
PM MAIL   Вверх
maxwel6064
Дата 6.3.2014, 17:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 5.3.2014

Репутация: нет
Всего: нет



В том то и дело, что обязательным условием является использование потоков....
PM MAIL   Вверх
jonie
Дата 7.3.2014, 10:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 22
Всего: 118



ну например можно использовать ###код в виде барьеров, например так:
Код

 class Program
    {
        static void Main(string[] args)
        {
            Thread w = new Thread(Worker);
            w.Start();

            var c1 = new Thread(CalcThread);
            var c2 = new Thread(CalcThread);

            c1.Start();
            c2.Start();

            Console.ReadLine();
        }

        private static volatile int _integer;
        static readonly Barrier _barrier0 = new Barrier(3);
        static readonly Barrier _barrier = new Barrier(3);

        static void Worker()
        {
            while (true)
            {
                ++_integer;
                _barrier0.SignalAndWait();
                Console.WriteLine("TID={0}, integer set to ={1}", Thread.CurrentThread.ManagedThreadId, _integer);
                _barrier.SignalAndWait();
            }
        }

        static void CalcThread()
        {
            while (true)
            {
                _barrier0.SignalAndWait();
                Console.WriteLine("TID={0}, integer={1}", Thread.CurrentThread.ManagedThreadId, _integer);
                Thread.Sleep(2000);
                _barrier.SignalAndWait();
            }
        }
    }


вместо барьеров можно использовать хоть семафоры, хоть Interlocked классы...


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
Certain
Дата 12.3.2014, 14:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 235
Регистрация: 18.6.2008
Где: Moscow

Репутация: 1
Всего: 4



Barrier это блокировка гибридного типа, т.е. если нет конкуренции на ресурс, крутится в пользовательском режиме (Interlocked), как только появляется конкуренция на блокировку ресурса, входит в режим ядра (семафоры, мьютексы и все события от EventWaitHandle). Barrier используется для одновременного запуска нескольких задач, как только заполнится резерв свободных мест, количество которых указанно в конструкторе. 
На изменения ProgressBar используйте BackgroundWorker, позволяет обновлять визуальные компоненты без маршалинга (обновление ProgressBar в обработчике OnProgressChanged), он неявно создаёт поток выполнения (событие DoWork).  В нем производите генерацию чисел в цикле, на каждой итерации создавайте в пуле потоков два потока (ThreadPool.QueueUserWorkItem, а лучше ThreadPool.RegisterWaitForSingleObject создаётся один раз и запускается по сигналу) на проверку чисел заданным условиям. Но после генерации числа и запуска потов нужно как-то синхронизировать их, т.е. должна произойти генерация числа в backgroundworker, следом запуск потоков на проверку, поток запуска ждет сигнала (ждать всех сигналов WaitHandle.WaitAll, можно использовать сигнальную конструкцию синхронизации потоков уровня ядра AutoResetEvent на каждую проверку или просто зацикливание на каких-то условиях), в потоках проверок в конце выполнения выставлять какие-нибудь флаги или сигналить этими AutoResetEvent, чтобы главный поток перешёл к следующей итерации.
Или использовать Task.Factory , тоже пул потоков, есть возможность создавать дочернии задачи, указывать в каком потоке выполнят задачу(синхронно, в новом потоке и т.п.), определение продолжений (ContinueWith) выпонения задачи, токены отмены и т.п.
Но самое главное, не нужно забывать, что многопоточность на одноядерных процессорах достигается путём квантования времени, а на многоядерных смесью истинного параллелизма и квантованием времени.

Это сообщение отредактировал(а) Certain - 12.3.2014, 15:28
--------------------
Работа программиста и шамана имеет много общего - оба боpмочyт непонятные слова, совершают непонятные действия и не могут объяснить, как оно работает.
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.1129 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.