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

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

Вернуться   Форум программистов > C/C++ программирование > Visual C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

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

Ответ
 
Опции темы Поиск в этой теме
Старый 02.12.2012, 21:24   #1
bors4
 
Регистрация: 30.07.2010
Сообщений: 4
Восклицание Поиск простых чисел потоками

Поиск простых чисел в указанном интервале чисел, разделенном на несколько диапазонов. Обработка каждого диапазона производится в порожденном процессе (потоке).
Нужна помощь никак не получается что-то путное сообразить. Точно не знаю, но кажется что CreateThread возвращает не то что нужно, в добавок к этому значение r не соразмерна с WAIT_OBJECT_0 или я что-то путаю. Так же не получается функции findPrimes передать аргумент с нормальным значение. Помогите разобраться пожалуйста.
Код:
#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include <windows.h>
#include <conio.h>

using namespace std;

#define NUM_THREADS 4 
#define MAX_NUMBERS 100
#define BLOCKSIZE (MAX_NUMBERS / NUM_THREADS) 
long primes[MAX_NUMBERS]; 
int primeCount;  

DWORD WINAPI findPrimes ( void *arg ) 
{ 
int tnum=0;
tnum = *(int *)arg; 
int start = tnum * BLOCKSIZE + 1; 
int end = tnum * BLOCKSIZE + BLOCKSIZE; 
int stride = 2; 
int number, factor; 
if(start == 1) start += stride; 
for (number = start; number < end; number += stride ) 
{ 
factor = 3; 
while ( (number % factor) != 0 ) factor += 2; 
if ( factor == number ) 
{  
primes[ primeCount ] = number; 
primeCount++;
cout<<primes[primeCount];
} 
} 
return 0; 
} 

int _tmain(int argc, _TCHAR* argv[])
{
int tnums[NUM_THREADS]; 
int i=0, rc=0; 
HANDLE h[NUM_THREADS];
primeCount = 0; 
primes[primeCount++] = 2; // handle special case 
printf( "Determining primes from 1 - %d \n", MAX_NUMBERS); 
DWORD r;
for ( i = 0; i < NUM_THREADS; ++i) 
{ 
tnums[NUM_THREADS] = i; 
h[NUM_THREADS] = CreateThread (NULL, 0,(LPTHREAD_START_ROUTINE) findPrimes, (void *)&tnums[i], 0, NULL); 
} 

printf( "Found %d primes\n", primeCount ); 
int  nthreads;
nthreads = NUM_THREADS;
while(nthreads>0)
{
		r=WaitForMultipleObjects(nthreads,h, FALSE, INFINITE);
		--nthreads;
		cout<<nthreads<<endl;
		cout<<h[nthreads]<<endl;
      if((r>=WAIT_OBJECT_0)&&(r<WAIT_OBJECT_0+nthreads)){
         i=r-WAIT_OBJECT_0;
         printf("Thread%d exit\n", tnums[i]);
         memcpy(&h[i], &h[i+1], (nthreads-i-1)*sizeof(h[0]));
         memcpy(&tnums[i], &tnums[i+1], (nthreads-i-1)*sizeof(tnums[0]));
         nthreads--;
      }
   }
getchar();
return 0;
}

Последний раз редактировалось Stilet; 02.12.2012 в 21:49.
bors4 вне форума Ответить с цитированием
Старый 02.12.2012, 22:40   #2
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

A зачем ждать каждый поток отдельно? Ждите прямо завершения всех рабочих потоков. Кроме того, у вас несколько потоков пишут в глобальные переменные - для этого надо делать синхронизацию, иначе не есть хорошо...
waleri вне форума Ответить с цитированием
Старый 02.12.2012, 23:02   #3
bors4
 
Регистрация: 30.07.2010
Сообщений: 4
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
A зачем ждать каждый поток отдельно? Ждите прямо завершения всех рабочих потоков.
Просто было бы хорошо показать на примере вывода в консоль сому концепцию потока, т.е. что потоки не упорядочены и в зависимости от объёма обрабатываемых данных могут завершать в разное время.
Цитата:
Кроме того, у вас несколько потоков пишут в глобальные переменные - для этого надо делать синхронизацию, иначе не есть хорошо...
Это тогда буду исправлять позже.

Так же уже нашёл ошибки - Run-Time Check Failure #2 - Stack around the variable '...' was corrupted.
Исправил в h[NUM_THREADS] = CreateThread (NULL, 0,(LPTHREAD_START_ROUTINE) findPrimes, (void *)&tnums[i], 0, NULL);
на h[NUM_THREADS-1]. Не знаю можно ли так, но ошибка пропала.
bors4 вне форума Ответить с цитированием
Старый 03.12.2012, 09:01   #4
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Цитата:
Сообщение от bors4 Посмотреть сообщение
Не знаю можно ли так, но ошибка пропала.
Можно то оно можно, но не нужно и неправильно.
У вас манипулятор всех потоков запишется в последний елемент массива. Если такова цель занятия, тогда зачем массив вообще а если нет, тогда пишите в каждый елемент массива.
waleri вне форума Ответить с цитированием
Старый 03.12.2012, 21:06   #5
bors4
 
Регистрация: 30.07.2010
Сообщений: 4
По умолчанию

Исправил код.
#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include <windows.h>
#include <conio.h>

using namespace std;

#define NUM_THREADS 4
#define MAX_NUMBERS 1000
#define BLOCKSIZE (MAX_NUMBERS / NUM_THREADS)
long primes[MAX_NUMBERS];
int primeCount;

DWORD WINAPI findPrimes(void *arg)
{
long tnum = *(long *)arg;
long start = tnum * BLOCKSIZE + 1;
long end = tnum * BLOCKSIZE + BLOCKSIZE;
long stride = 2;
long number, factor;
if(start == 1) start += stride;
for (number = start; number < end; number += stride )
{
factor = 3;
while ( (number % factor) != 0 ) factor += 2;
if ( factor == number )
{
primes[ primeCount ] = number;
primeCount++;
cout<<number<<endl;
}
}
return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
int i;
long tnums[NUM_THREADS];
HANDLE h[NUM_THREADS];
HANDLE hMutex;
hMutex = CreateMutex( NULL, FALSE, NULL);
primeCount = 0;
primes[primeCount++] = 2;
printf( "Determining primes from 1 - %d \n", MAX_NUMBERS);
for (i=0; i<NUM_THREADS;++i)
{
tnums[i] = i;
h[NUM_THREADS] = CreateThread (NULL,0,findPrimes,(void*)&tnums[i],0,NULL);
cout<<"i="<<tnums[i]<<endl;
}
DWORD rc;
ReleaseMutex(hMutex);
printf( "Found %d primes\n", primeCount );
_getch();
return 0;
}
Всё бы хорошо но есть два небольших недочёта:1) h[NUM_THREADS]=CreatThread(...) оставил как в принципе и должно быть что и вернуло ошибку Run-Time Check Failure #2 - Stack around the variable 'h' was corrupted. 2) так же есть вывод простых чисел но не всех(на промежутке от 1 до 100 пропущено 11 простых чисел и ещё 15 выводятся может быть дело даже в алгоритме?). Также не знаю правильно ли использовал мьютексы.

Последний раз редактировалось bors4; 03.12.2012 в 21:10.
bors4 вне форума Ответить с цитированием
Старый 04.12.2012, 00:08   #6
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

h[NUM_THREADS] - это за пределами массива.
waleri вне форума Ответить с цитированием
Старый 04.12.2012, 19:36   #7
bors4
 
Регистрация: 30.07.2010
Сообщений: 4
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
h[NUM_THREADS] - это за пределами массива.
Это исправил. Осталась одна проблемка. Если я правильно понял, то почему-то создаётся 4 потока, но простые числа ищут только 2 из них. В чём может быть дело?
bors4 вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Поиск всех простых чисел, не превосходящих заданного N Placebo228 Общие вопросы C/C++ 1 06.11.2012 22:42
Поиск простых чисел phreaker228 Помощь студентам 3 03.06.2012 15:24
Поиск простых чисел + поток (C++) Brabus Помощь студентам 4 30.09.2011 08:46
Поиск простых чисел из диапазона dex92 Помощь студентам 2 21.05.2010 09:40
поиск простых чисел методом решета.программа на С или С++ из_семи Помощь студентам 2 25.02.2009 20:56