Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 5.00/14: Рейтинг темы: голосов - 14, средняя оценка - 5.00
4 / 4 / 2
Регистрация: 05.02.2013
Сообщений: 441
1

Функция WaitForMultipleObjects выбрасывает поток

29.10.2013, 12:09. Показов 2907. Ответов 20
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет. Создаю поток( пусть будет поток А ) и ожидаю события на WaitForMultipleObjects. Одновременно считываю из звуковой карты данные , после считывания 44100*2 байт сигнализирую потоку А, поток А в свою очередь начинает считать преобразование Фурье и выводить на экран. Сигнал происходит и после метки в 88200*2 байт и так же сигнализирует потоку А.

Проблема вся в том , что поток А не успевает всё посчитать , как приходит новое событие и почему то поток вылетает ( по карайней мере на бряки не реагирует ).

Что делает функция WaitForMultipleObjects когда поступает очередное событие , а на ней никто не ожидает ?

Использую DirectDraw и DirectSound.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
29.10.2013, 12:09
Ответы с готовыми решениями:

В какой библиотеке лежит функция WaitForMultipleObjects?
подключаю библиотеку апи, но пишет, что не продекларировано. #include <windows.h> #include...

Пайпы и WaitForMultipleObjects
Добрый день. Имеется несколько пайпов, созданных через CreatePipe. В каждый из них перенаправляется...

Какая низкоуровневая функция из Windows API вызывается когда создается поток thread ?
Какая низкоуровневая функция из Windows API вызывается когда создается поток thread ? Заранее...

Функция WaitForMultipleObjects
Здравствуйте! В программе есть несколько процедур, которые выполняются за определённое время (по...

20
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
29.10.2013, 12:18 2
Приведите минимальный код, воспроизводящий проблему.
Или хотя бы псевдокод.
0
4 / 4 / 2
Регистрация: 05.02.2013
Сообщений: 441
29.10.2013, 12:23  [ТС] 3
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
// Запускаю поток А и начинаю считыать из буфера
 
BOOL start(HWND hWnd)
{
    if( !CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)DrawWnd,(PVOID)hWnd,0,&ThreadId) )
    {
    MessageBox( hWnd, (LPCTSTR)"Не удалось создать поток", (LPCTSTR)"Error", MB_OK );
    return FALSE;
    }
EnableMenuItem(GetMenu(hWnd),ID_START,MF_DISABLED);
EnableMenuItem(GetMenu(hWnd),ID_STOP,MF_ENABLED);
lpDsoundBuffer->Start(DSCBSTART_LOOPING);
StartThread = TRUE;
return TRUE;
}
 
 
// Функция потока А
 
BOOL DrawWnd( PVOID hwnd )
{       
    HWND hwd = (HWND) hwnd;
    DDSURFACEDESC2 desc;
    DWORD OffSetBuffSound;
    VOID *ptr1 = NULL;
    VOID *ptr2 = NULL;
    DWORD dwSize1 = 0;
    DWORD dwSize2 = 0;
    DWORD dwsize = 0;
    WORD Databuf[SOUND_BUFFER_SIZE/2];
    DOUBLE AmplSpectrum[SOUND_BUFFER_SIZE/2];
    DOUBLE Im = 0, Re = 0;
    DOUBLE summaRe = 0, summaIm = 0;
    DOUBLE Arg = 0,PI = 3.141592653;
    int a = 0;
    WORD * ptr;
 
    while(StartThread)
    {   
    
    WORD dwvent = WaitForMultipleObjects(2,hEvents,FALSE,INFINITE);
    dwvent -= WAIT_OBJECT_0;    
    OffSetBuffSound =   pDSPosNotifies[dwvent == 0 ? 1 : 0].dwOffset;
    
    if( lpDsoundBuffer->Lock(OffSetBuffSound,SOUND_BUFFER_SIZE,&ptr1,&dwSize1,&ptr2,&dwSize2,0) == DD_OK )
    {               
        ptr =  dwvent == 0 ? (WORD *) ptr2 : (WORD *) ptr1;     
    
        /*
            Здесь считается Фурье
               */
    lpDsoundBuffer->Unlock(ptr1,dwSize1,ptr2,dwSize2);
    }
    
    ZeroMemory( &desc,sizeof(desc) );
    desc.dwSize = sizeof( desc );   
    
    if( lpDDrawSurfsOutSide->Lock(0,&desc,DDLOCK_WAIT,NULL) == DD_OK )
    {
         DWORD * dst = (  DWORD *) desc.lpSurface;
         DWORD  ycurr;
 
        /*
                 Здесь вывожу на экран
               */
 
        lpDDrawSurfsOutSide->Unlock(0);
    }
 
    RECT RectStart;
    POINT PoStart;
    PoStart.x = 0;
    PoStart.y = 0;
    ClientToScreen(hwd,&PoStart);
    GetClientRect(hwd,&RectStart);
    OffsetRect(&RectStart,PoStart.x,PoStart.y);
    
    lpDDrawSurfPrimary->Blt(&RectStart,lpDDrawSurfsOutSide,NULL,DDBLT_WAIT,NULL);
    a+=100;
    }
    return TRUE;
}

Могу привести полностью код
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
29.10.2013, 12:32 4
Цитата Сообщение от Abraziv__ Посмотреть сообщение
BOOL DrawWnd( PVOID hwnd )
Сигнатура функции потока неверная.
Она возвращает DWORD, а не int, и должна быть __stdcall.

Цитата Сообщение от Abraziv__ Посмотреть сообщение
while(StartThread)
Поток успевает запуститься до того, как StartThread будет установлен в TRUE.

Кстати, в каком месте код вылетает ?
И как создаются event-ы ?
0
4 / 4 / 2
Регистрация: 05.02.2013
Сообщений: 441
29.10.2013, 12:39  [ТС] 5
Спасибо учту.

События создаются так:
C++
1
2
3
4
5
6
7
8
for(int i = 0; i < 2; i++ )
    {
    hEvents[i] = CreateEvent(NULL,FALSE,FALSE,NULL);
        if( !hEvents[i] )
        {
        MessageBox( hDlg, (LPCTSTR)"Не удалось создать события CreateEvent ", (LPCTSTR)"Error", MB_OK );
        return FALSE;
        }
Добавлено через 3 минуты
Забыл сказать. Вылетает не досчитав преобразование Фурье. И это не доступ к запрещённой области памяти. А просто вылетает(безмолвно). Я как понял винда сама завершает поток А, если тот не сидел на функции WaitForMultipleObjects , когда произошёл сигнал.
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
29.10.2013, 12:46 6
Цитата Сообщение от Abraziv__ Посмотреть сообщение
Я как понял винда сама завершает поток А, если тот не сидел на функции WaitForMultipleObjects , когда произошёл сигнал.
Нет, такого точно не может быть.
SetEvent просто устанавливает событие в сигнальное состояние и все.
На код, который не ждет этого события, этот факт никак не влияет.

А SOUND_BUFFER_SIZE чему равен, кстати ?
0
4 / 4 / 2
Регистрация: 05.02.2013
Сообщений: 441
29.10.2013, 12:47  [ТС] 7
Я тогда не понимаю, с чем это может быть связанно. Если уменьшить нагрузку на поток, то всё работает нормально.

Добавлено через 39 секунд
#define SOUND_BUFFER_SIZE 44100 * 2
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
29.10.2013, 12:58 8
Цитата Сообщение от Abraziv__ Посмотреть сообщение
#define SOUND_BUFFER_SIZE 44100 * 2
Ага, вот кое-что начинает вырисовываться.
Размер стека, который по умолчанию резервируется для каждого потока - 1 мегабайт.
В Вашем коде есть парочка массивов на стеке, которые имеют подозрительно большой размер.
Подсказка: попробуйте выделять их в динамической памяти.

Цитата Сообщение от Abraziv__ Посмотреть сообщение
И это не доступ к запрещённой области памяти. А просто вылетает(безмолвно).
Симптомы очень похожи на переполнение стека.
0
4 / 4 / 2
Регистрация: 05.02.2013
Сообщений: 441
29.10.2013, 16:31  [ТС] 9
Ещё раз самоутверждаюсь в вашей светлой голове. Сейчас попробую.

Добавлено через 9 минут
Короче поток А, крутится здесь( в циклах):

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
if( lpDsoundBuffer->Lock(OffSetBuffSound,SOUND_BUFFER_SIZE,&ptr1,&dwSize1,&ptr2,&dwSize2,0) == DD_OK )
    {               
        ptr =  dwvent == 0 ? (WORD *) ptr2 : (WORD *) ptr1;     
    
        for( int i = 0; i < SOUND_BUFFER_SIZE/2 ; i++ )
        {
            summaRe = 0; summaIm = 0;
            for( int j = 0; j < SOUND_BUFFER_SIZE/2 ;j++ )
            {
                Arg = 2.0*PI*j*i/SOUND_BUFFER_SIZE/2;   
                Re = cos(Arg)*(ptr[j]);
                Im = sin(Arg)*(ptr[j]);
                summaRe = summaRe + Re;
                summaIm = summaIm + Im;
            }
            AmplSpectrum[i] = sqrt(summaRe*summaRe + summaIm*summaIm);
        
        }   
    lpDsoundBuffer->Unlock(ptr1,dwSize1,ptr2,dwSize2);
    }
Неужели так долго считает.

Добавлено через 3 минуты
Вообщем я походу зря панику навёл. Это он так долго походу считает ))))))))))) Мдя....

Добавлено через 1 минуту
Да. ТАк и есть извиняюсь за свою тупость. Походу облом с ФФТ.

Добавлено через 3 часа 13 минут
А вы не знаете случаем, почему так долго может считаться два цикла 44100*44100 , это же не сильно много ?!
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
29.10.2013, 16:40 10
Почти два миллиарда 1 944 810 000 это по-вашему не много?
Внутри цикла куча умножений, делений, есть синус, косинус, квадратный корень...
0
4 / 4 / 2
Регистрация: 05.02.2013
Сообщений: 441
29.10.2013, 16:44  [ТС] 11
Аналогичное делает знакомый, у него меньше чем за сек всё обрабатывает. Скидывал проект мне, тоже очень быстро считает. Тоже самое ФФт
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
29.10.2013, 16:50 12
А ты покажи код друга.
Друг, например, может использовать другие флаги оптимизации. Причин может быть много.
0
4 / 4 / 2
Регистрация: 05.02.2013
Сообщений: 441
29.10.2013, 17:16  [ТС] 13
Почему при выборе релиз , не хочет открывать #pragma comment(lib,"ddraw.lib") незнаете случаем почему ?

Друг пишет на С#, я под winAPI. Никаких флагов он не использует.

Вот егошний код
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Numerics;
 
namespace DirectSoundMy
{
    class FFT
    {
      
        
        private static Complex w(int k, int N, bool b)
        {
            Complex j = new Complex(0, 1);
            if (k % N == 0) return new Complex(1, 0);
            double arg; if (!b) arg = -2 * Math.PI * k / N; else arg = 2 * Math.PI * k / N;
            return new Complex(Math.Cos(arg), Math.Sin(arg));
        }
 
        public static Complex[] fft(Complex[] x, bool b)
        {
            Complex[] X;
            int N = x.Length;
 
            if (N == 0)
            {
                X = new Complex[2];
                X[0] = new Complex(0, 0);
                X[1] = new Complex(0, 0);
                return X;
            }
 
 
            if (N == 2)
            {
                X = new Complex[2];
                X[0] = x[0] + x[1];
                X[1] = x[0] - x[1];
            }
            else
            {
                Complex[] x_even = new Complex[N / 2];
                Complex[] x_odd = new Complex[N / 2];
                for (int i = 0; i < N / 2; i++)
                {
                    x_even[i] = x[2 * i];
                    x_odd[i] = x[2 * i + 1];
                }
                Complex[] X_even = fft(x_even, b);
                Complex[] X_odd = fft(x_odd, b);
                X = new Complex[N];
                for (int i = 0; i < N / 2; i++)
                {
                    X[i] = X_even[i] + w(i, N, b) * X_odd[i];
                    X[i + N / 2] = X_even[i] - w(i, N, b) * X_odd[i];
                }
              }
            return X;
 
        //    Complex[] X_n = new Complex[N];
        //    for (int i = 0; i < N / 2; i++)
         //   {
        //        X_n[i] = X[N / 2 + i];
        //        X_n[N / 2 + i] = X[i];
        //    }
         //   return X_n;
 
        }
 
    }
}
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
29.10.2013, 17:21 14
Цитата Сообщение от Abraziv__ Посмотреть сообщение
незнаете случаем почему ?
Нет, не знаю.
А ты не заметил что у него другой алгоритм вычисления FFT ? Какой размер FFT использует он? Обычно, при вычислении FFT берут размер равный степени двойки, т.е. 256, 512, 1024.. куда тебе 44100 ?
0
4 / 4 / 2
Регистрация: 05.02.2013
Сообщений: 441
29.10.2013, 17:27  [ТС] 15
Какая разница какой размр брать? У меня в данном случае размер буфера звуковой карты.
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
29.10.2013, 17:29 16
Честно говоря, мне не хочется учить тебя тому, для чего используется FFT и где он применяется. Если ты сам этого не понимаешь тогда тебе стоит об этом побольше почитать, ну или спросить об этом друга.
0
4 / 4 / 2
Регистрация: 05.02.2013
Сообщений: 441
29.10.2013, 17:51  [ТС] 17
Если честно я знаю что такое ФФТ и знаю где оно применяется и применял уже не раз. ФФТ к твоему сведению считается по длительности сигнала. А она не всегда равна степени двойки !!!!!
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
29.10.2013, 18:20 18
Ну ты прям мне глаза открыл. Не знаю как и благодарить даже..
Существует куча оптимизированных алгоритмов для вычисления БПФ в реальном времени, и все они используют размер равный степени двойки. Ты же делаешь всё это через одно место.
0
4 / 4 / 2
Регистрация: 05.02.2013
Сообщений: 441
29.10.2013, 18:23  [ТС] 19
В плане оптимизации, не спорю надо что то думать. Может даже и SSE подключать сюда.
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
29.10.2013, 18:33 20
Вот хорошая реализация с размером 2^n.
Кликните здесь для просмотра всего текста
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include <cmath>
 
#define PI          3.1415926535897932384626433832795
#define TWOPI       6.28318530717958647692528676655901
 
// data[i][0] - real part
// data[i][1] - imagine part
// length = 1 << len_pow
void fft( float (*data)[2], int len_pow )
{
    int len;
    int n1, n2, n4;
    int i0, i1, i2, i3;
    int i, j, k, id, isxx;
    float   a, e, r1, r2, s1, s2, s3;
    float   a3, ss1, ss2, cc1, cc2;
 
    len = 1 << len_pow;
 
    n1 = len - 1;
    n2 = len << 1;
    for ( k = 1; k < len_pow; k++ ) {
        n2 >>= 1;
        n4 = n2 >> 2;
        e = TWOPI / (float)n2;
        a = 0.0;
        for ( j = 1; j <= n4; j++ ) {
            a3 = a + a + a;
            ss1 = sin( a );
            ss2 = sin( a3 );
            cc1 = cos( a );
            cc2 = cos( a3 );
            isxx = j;
            id = n2 << 1;
            while ( isxx < len ) {
                for ( i0 = isxx - 1; i0 < n1; i0 += id ) {
                    i1 = i0 + n4;
                    i2 = i1 + n4;
                    i3 = i2 + n4;
 
                    r1 = data[i0][0] - data[i2][0];
                    data[i0][0] += data[i2][0];
 
                    r2 = data[i1][0] - data[i3][0];
                    data[i1][0] += data[i3][0];
 
                    s1 = data[i0][1] - data[i2][1];
                    data[i0][1] += data[i2][1];
 
                    s2 = data[i1][1] - data[i3][1];
                    data[i1][1] += data[i3][1];
 
                    s3 = r1 - s2;
                    r1 += s2;
                    s2 = r2 - s1;
                    r2 += s1;
 
                    data[i2][0] =  r1 * cc1 - s2 * ss1;
                    data[i2][1] = -s2 * cc1 - r1 * ss1;
                    data[i3][0] =  s3 * cc2 + r2 * ss2;
                    data[i3][1] =  r2 * cc2 - s3 * ss2;
                }
                isxx = (id << 1) - n2 + j;
                id <<= 2;
            }
            a = (float)j * e;
        }
    }
 
    /* last stage, length = 2 butterfly */
    isxx = 1;
    id = 4;
    while ( isxx < len ) {
        for ( i1 = isxx; i1 <= len; i1 += id ) {
            i0 = i1 - 1;
            r1 = data[i0][0];
            data[i0][0] = r1 + data[i1][0];
            data[i1][0] = r1 - data[i1][0];
            r1 = data[i0][1];
            data[i0][1] = r1 + data[i1][1];
            data[i1][1] = r1 - data[i1][1];
        }
        isxx = (id << 1) - 1;
        id <<= 2;
    }
 
    /* bit reverse counter */
    j = 0;
    for ( i = 0; i < len - 1; i++ ) {
        if ( i < j ) {
            r1 = data[i][0];
            data[i][0] = data[j][0];
            data[j][0] = r1;
            r1 = data[i][1];
            data[i][1] = data[j][1];
            data[j][1] = r1;
        }
        k = len >> 1;
        while ( k <= j ) {
            j -= k;
            k >>= 1;
        }
        j += k;
    }
}
0
29.10.2013, 18:33
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
29.10.2013, 18:33
Помогаю со студенческими работами здесь

Функция:выбрасывает из списка одинаковые элементы.
Нужно написать функцию,которая выбрасывает из списка одинаковые элементы.Помогите)

Функция:выбрасывает из списка одинаковые элементы.
Создать список на языке С++,который разрешает создать односторонний связанный список(используя...

Функция,выбрасывает из списка одинаковые элементы
Нужно создать функцию,которая выбрасывает из списка одинаковые элементы :) Помогите,пожалуйста:)

Функция rand() в обоих случаях выбрасывает одинаковые числа
Почему в итоге всегда функция rand() в обоих случаях выбрасывает одинаковые числа, а выбрасывать...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru