Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Вот тут фигня какая-то получается... / 6 сообщений из 6, страница 1 из 1
27.04.2005, 02:33
    #33037274
XED
XED
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот тут фигня какая-то получается...
Ну да, в натуре...
Я ничего не могу понять - почему не работает? Может есть какие мысли?
Немного поясню: это учебная программка, другу в универе задали. Задан массив (по условию большой) каким-то образом заполненный (не важно, по крайней мере пока не важно). Необходимо найти элемент в массиве ниаболее близкий к среднему арифметическому, используя для выполнения основных функций отдельные нити. Очевидно, что использование CreateThread здесь не уместно, даже приодится ждать результата:

do
GetExitCodeThread (hThread, &result);
while (result == STILL_ACTIVE);

но тем не менее - так надо... Поэтому приняв ТАКИЕ правила, посмотрите, пожалуйста, исходник и скажите ПОЧЕМУ не работает? (Там возвращается что-то не то при втором вызове, хотя при ретурне из функции ThreadFunc2 вроде всё в поряде...)

И ещё. Результатом потока может быть только DWORD? А если я чё другое хочу?

Код: plaintext
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.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
//---------------------------------------------------------------------------

#include <windows.hpp>
#include <stdio.h>      // для sprintf
#pragma hdrstop
//---------------------------------------------------------------------------
#define ARR_TYPE    short
#define ARR_RANGE    1000 
//---------------------------------------------------------------------------

typedef struct {
    float (*func)(ARR_TYPE*, WORD);
    /* аргументы этой ф-ции: */
        ARR_TYPE* mas;
        WORD range;
    } THREAD_PARAM_forCOUNT, * LPTHREAD_PARAM_forCOUNT;

typedef struct {
    ARR_TYPE (*func)(ARR_TYPE*, WORD, float);
    /* аргументы этой ф-ции: */
        ARR_TYPE* mas;
        WORD range;
        float middle;
    } THREAD_PARAM_forFIND, * LPTHREAD_PARAM_forFIND;

//---------------------------------------------------------------------------

float CountMiddle   (ARR_TYPE*, WORD);
ARR_TYPE FindMiddle (ARR_TYPE*, WORD, float);

DWORD WINAPI ThreadFunc1 (LPVOID);
DWORD WINAPI ThreadFunc2 (LPVOID);

//---------------------------------------------------------------------------

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
  //randomize();
  ARR_TYPE* mas;
  float FoundNumber;
  char  strTemp[ 255 ];
  /* Перменные, необходимы для потоков */
  DWORD idThread;
  THREAD_PARAM_forCOUNT ThreadParam1;
  THREAD_PARAM_forFIND  ThreadParam2;
  HANDLE hThread;
  DWORD result;

  if ( !(mas = new ARR_TYPE [ARR_RANGE]) ) {
    MessageBox (NULL, "There is some problem with memory allocation", "Program with threads", MB_OK);
    return - 1 ;
    }

  /* Вызов первого потока с функцией CountMiddle */
  ThreadParam1.func  = CountMiddle;
  ThreadParam1.mas   = mas;
  ThreadParam1.range = ARR_RANGE;

  hThread = CreateThread (NULL,  0 ,  ThreadFunc1,  &ThreadParam1,  0 , &idThread);
  do
    GetExitCodeThread (hThread, &result);
  while (result == STILL_ACTIVE);

  /* Вызов второго потока с функцией FindMiddle */
  ThreadParam2.func   = FindMiddle;
  ThreadParam2.mas    = mas;
  ThreadParam2.range  = ARR_RANGE;
  ThreadParam2.middle = result;

  hThread = CreateThread (NULL,  0 ,  ThreadFunc2, &ThreadParam2,  0 , &idThread);
  do
    GetExitCodeThread (hThread, &result);
  while (result == STILL_ACTIVE);

  //FoundNumber = FindMiddle (mas, ARR_RANGE, CountMiddle (mas, ARR_RANGE));
  FoundNumber = result;
  sprintf (strTemp, "There is %g number is the nearest to middle", FoundNumber);
  MessageBox (NULL, strTemp, "Program with threads", MB_OK);
  delete [] mas;
  return  0 ;
}
//---------------------------------------------------------------------------

float CountMiddle   (ARR_TYPE* mas, WORD count) {
/* Сразу заполняет массив ивозвращает среднее значение */
  double Sum =  0 ;
  for (WORD i= 0 ; i<count; i++)
    Sum += mas[i] = i;
  return (float)(Sum/count);
  }

ARR_TYPE FindMiddle (ARR_TYPE* mas, WORD count, float number) {
/* Собственно, ищет наиболее близкий к среднему значению элемент */
  ARR_TYPE temp = mas[ 0 ];
  for (WORD i= 1 ; i<count; i++)
    if ( abs(mas[i]-number) < abs(temp-number) )
      temp = mas[i];
  return temp;
  }

DWORD WINAPI ThreadFunc1 (LPVOID argument) {
  THREAD_PARAM_forCOUNT temp;
  float result;

  temp = *(LPTHREAD_PARAM_forCOUNT)argument;
  result = temp.func (temp.mas, temp.range);
  return (DWORD)result;
  }

DWORD WINAPI ThreadFunc2 (LPVOID argument) {
  THREAD_PARAM_forFIND temp;
  ARR_TYPE result;

  temp = *(LPTHREAD_PARAM_forFIND)argument;
  result = temp.func (temp.mas, temp.range, temp.middle);
  return (DWORD)result;
  }

Заранее пасиб!
...
Рейтинг: 0 / 0
28.04.2005, 15:25
    #33040748
XED
XED
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот тут фигня какая-то получается...
Блин, неужели никто не может сказать в чём ошибка?
...
Рейтинг: 0 / 0
28.04.2005, 15:42
    #33040840
roman10
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот тут фигня какая-то получается...
Написано до пупа всего, и много лишнего. Но просмотрев код "по диагонали", я ошибок не нашел. Что у вас конкретно не работает?

авторОчевидно, что использование CreateThread здесь не уместно, даже приодится ждать результатаПочему неуместно? Ведь сказано, что нужно использовать нити. Ждать результат конечно приходится, ведь вы ничего не делаете в основом потоке.

Код: plaintext
1.
2.
3.
do
GetExitCodeThread (hThread, &result);
while (result == STILL_ACTIVE);
Лучше заменить на WaitForSingleObject(hThread, INFINITE).

авторРезультатом потока может быть только DWORD? А если я чё другое хочу? Результа потока -- это код возврата (0, если поток завершился успешно). Все остальное передавайте, например, через глобальные переменные (а вообще это большая тема, относящаяся к IPC).
...
Рейтинг: 0 / 0
28.04.2005, 16:00
    #33040922
XED
XED
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот тут фигня какая-то получается...
roman10
WaitForSingleObject(hThread, INFINITE).

хоть на этом спасибо
roman10
Результа потока -- это код возврата (0, если поток завершился успешно). Все остальное передавайте, например, через глобальные переменные (а вообще это большая тема, относящаяся к IPC).
Не проблема, но бывают случаи, кога глобальными переменными не обойдёшься, а это так, учебная программка...
...
Рейтинг: 0 / 0
28.04.2005, 16:25
    #33041027
roman10
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот тут фигня какая-то получается...
авторНе проблема, но бывают случаи, кога глобальными переменными не обойдёшься, а это так, учебная программка...
Ах да. Ведь вы результат работы CountMiddle, возвращающей тип float, преобразовываете в DWORD. Очень здорово придумано. Это явная ошибка.

Вам нужно было в THREAD_PARAM_forCOUNT предусмотреть отдельное поле для возврата результата, да и THREAD_PARAM_forFIND, кстати, тоже.
...
Рейтинг: 0 / 0
28.04.2005, 17:20
    #33041235
XED
XED
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот тут фигня какая-то получается...
Да, конечно... Это можно рассматривать как простую глупость... Уже всё исправлено... :)
Пасиб....
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Вот тут фигня какая-то получается... / 6 сообщений из 6, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]