Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2002.10.10;
Скачать: [xml.tar.bz2];

Вниз

Критические секции в потоке   Найти похожие ветки 

 
Zergling   (2002-10-01 08:41) [0]

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

var CS:TRTLCriticalSection;

procedure TSpeakPlay.Execute;
begin
EnterCriticalSection(CS); // Начало критической секции
Speak_Violation(FTypeViolation,FTypeParametr,FShortPosName,FDifference);
LeaveCriticalSection(CS); // Конец критической секции
end;

procedure TMainForm.Button1Click(Sender: TObject);
var Tst:TSpeakPlay;
begin
InitializeCriticalSection(CS); // Инициализация критической секции
tst:=TSpeakPlay.Create(0,"p","310/2",0); // Создаем поток
end;

Speak_Violation() использует в работе эту процедуру:

Procedure Speak(File_Name:String);
Begin
// EnterCriticalSection(CS); // Пробовал указать сдесь критические секции,
// но не лечится
MainForm.MyTalk.FileName:=File_Name;
MainForm.MyTalk.open;
MainForm.MyTalk.Wait:=True; // Delphi вываливается сдесь при создании 2-го потока
// говоря, что устройство MCI занято
MainForm.MyTalk.Play;
// LeaveCriticalSection(CS);
End;


 
Digitman   (2002-10-01 08:48) [1]


> вновь созданный поток доходя до критической секции ждет
> звершения работы предыдущего потока


Не так. Поток (2), вызывающий EnterCriticalSection, "засыпает", если другой поток (1) ранее вызвал EnterCriticalSection той же крит.секции, до момента вызова потоком (1) LeaveCriticalSection.


 
Zergling   (2002-10-01 10:47) [2]

Digitman ©
Второй поток у меня почему то не засыпает.
Пытается воспроизвести звук через Медиаплейер


 
Polevi   (2002-10-01 11:30) [3]

ты уверен что твой SpeakViolation не возвращает упарвление до того как завершит воспроизведение звука ?


 
Digitman   (2002-10-01 11:52) [4]

Так у тебя ж каждый новый поток работает со своей собственной крит.секцией, а не с единой для всех потоков !

procedure TMainForm.Button1Click(Sender: TObject);
var Tst:TSpeakPlay;
begin
InitializeCriticalSection(CS); // Инициализация НОВОЙ критической секции !! Старая потеряна навсегда !
tst:=TSpeakPlay.Create(0,"p","310/2",0); // Создаем НОВЫЙ поток, который будет обращаться к НОВОЙ крит.секции !
end;


а нужно что-то вроде этого :

InitializeCriticalSection(CS); // новая крит.секция

// стартуем несколько код.потоков подряд - всем им передаем
//параметром одну и ту же крит.секцию, по которой они будут синхронизировать доступ к MCI как неразделяемому ресурсу :

try
TSpeakPlay.Create(0,"p","310/2",0, CS);
TSpeakPlay.Create(0,"p","310/2",0, CS);
TSpeakPlay.Create(0,"p","310/2",0, CS);
finally
DeleteCriticalSection(CS); // уничтожаем секцию - больше не нужна она
end;



 
Digitman   (2002-10-01 11:56) [5]

миль пардон - нужно еще дождаться завершения выполнения всех потоков, обращающихся к секции , прежде чем ее уничтожать
InitializeCriticalSection(CS); // новая крит.секция

try
TSpeakPlay.Create(0,"p","310/2",0, CS);
TSpeakPlay.Create(0,"p","310/2",0, CS);
TSpeakPlay.Create(0,"p","310/2",0, CS);
finally
if Все_потоки_использующие_эту_CS_завершились then
DeleteCriticalSection(CS);
end;




 
Zergling   (2002-10-01 14:18) [6]

Digitman ©
InitializeCriticalSection(CS); я поместил в OnCreate формы,
а DeleteCriticalSection(CS); в OnDestroy формы.
Обязательно ли CS передовать в поток при его создании т.к.
она у меня глобальная.
И вот проблема. Второй поток ждет завершения рботы первого,
но при воспроиведении 2-го потока дельфи полностью
выпадает (причем часть звуков 2-й поток успевает проигрывать),
ссылаясь на ошибку в библиотеке kernel32.dll. Вчем еще может быть причина.


 
Digitman   (2002-10-01 14:31) [7]


> InitializeCriticalSection(CS); я поместил в OnCreate формы,
> а DeleteCriticalSection(CS); в OnDestroy формы.


В изначальном коде, приведенном тобой, этого не видно. Поэтому и рекомендация была дана.


> Обязательно ли CS передовать в поток при его создании т.к.
> она у меня глобальная.


Необязательно. Это - как один из возможных вариантов для общего случая, когда отдельно создаваемая секция служит для защиты отдельного неразделяемого ресурса.


> Второй поток ждет завершения рботы первого


Да на здоровье) .. Только - причем здесь крит.секция ?


> но при воспроиведении 2-го потока дельфи полностью
> выпадает


Куда ? В осадок ? Что есть "дельфи ... выпадает" ? Мы таки ведем речь о Делфи (как об инструменте) или все же о твоем приложении (созданном средствами этого инструмента и неработающем в результате) ?


> ссылаясь на ошибку в библиотеке kernel32.dll. Вчем еще может
> быть причина.


Еще ?? Кроме какой ? Какова же первая причина и причина ЧЕГО ?


 
Polevi   (2002-10-01 14:40) [8]

работай лучше с ивентами

OnCreate
begin
FEvent:=CreateEvent(nil,false,true,nil)
..
end;


TTHread.Execute
begin
try
WaitForSingleObject(FEvent,INFINITE);
Play;
finally
SetEvent(FEvent);
end
end



 
Smithson   (2002-10-01 14:57) [9]

У меня теже яйца в XP и при работе с wininet.dll. Видимо, проблемы реализации критических секций. Попробуй поменять способ синхронизации - мутекс, memvapfile или события.


 
Digitman   (2002-10-01 15:11) [10]

не городите чушь) ... крит.секции нормально работают на любой из Win32-платформ. И предназначены они в 1-ю очередь как раз для межпоточной синхронизации неразд.ресурсов в контексте одного и того же процесса. А вот когда нужна межпроцессная синхронизация - тогда и мьютексы/семафоры/ивенты к месту.


 
Polevi   (2002-10-01 15:22) [11]

2Digitman © (01.10.02 15:11)
иногда проще решить проблему переписав код заново :-)


 
Digitman   (2002-10-01 15:50) [12]

>Polevi

... чтобы получить теми же граблями по тому же лбу)))) ... ибо нет понимания сути


 
Zergling   (2002-10-01 16:09) [13]

Digitman ©
Твои подсказки по критическим секциям мне очень помогли (все работает). За что большое спасибо. При полном исследовании своей проги выяснилось, что глюк вызывет Медиаплейер при попытке воспроизвести звук.
Хотя при работе первого потока воспроизводятся все звуки, а вылетет приложение при воспроизведении звуков во втором созданном потоке. Думаю, что нужно произвети синхронизаию обращения к VCL TMediaPlayer в потоке. Если у кого то другие соображения (или знаете ссылку где можно прочитть по этой проблеме), нпишите пожалуйста.


 
Polevi   (2002-10-01 16:10) [14]

>Digitman
если не дурак, то еще одна шишка пойдет впрок :-0

>Zergling (01.10.02 08:41)
и правда, почитай рихтера или харта про синхронизацию потоков


 
Digitman   (2002-10-01 16:13) [15]

>Zergling

А если таки потребуется синхронизация с осн.потоком, то и крит.секции не нужны будут


 
Zergling   (2002-10-01 16:22) [16]

Все ясно. ВСЕМ СПАСИБО!!!



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2002.10.10;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.008 c
1-31764
Hammer1
2002-10-01 09:08
2002.10.10
DELPHI и VB


1-31870
vixic
2002-09-27 08:42
2002.10.10
Скрипты!


1-31871
sagchat
2002-09-29 15:53
2002.10.10
Случайный текст.


1-31869
Алексей Смирнов
2002-09-28 21:02
2002.10.10
Массив компонентов


1-31707
Ago
2002-09-27 18:46
2002.10.10
ComboBox1 с картинками... возможно?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский