в чём может быть проблема
Может быть в том, что все потоки ждут сообщения, а не отсылают его.
Ведь такая ситуация может произойти.
PureBasic - форум |
Привет, Гость! Войдите или зарегистрируйтесь.
Вы здесь » PureBasic - форум » Вопросы по PureBasic » Вопросы новичка (продолжение…)
в чём может быть проблема
Может быть в том, что все потоки ждут сообщения, а не отсылают его.
Ведь такая ситуация может произойти.
Пётр, врядли дело в этом, такая ситуация (все потоки ждут сообщения и не пишут возможна), но ведь там в определённый момент эта ситуация начинается и не заканчиваться. Не дело же в рандоме, не может же он после определённого момента выдаватькаждый раз одинаковое значение (0 - принять, 1 - отправить), может дело в семафоре и мьютексе, но как их тогда использовать?
может дело в семафоре и мьютексе, но как их тогда использовать?
Вот и я о том же.
Скорее всего потоки блокируются семафором потому что ждут приема команд, а не передают их.
http://ru.wikipedia.org/wiki/Взаимная_блокировка
Без семафора не зависает.
По моему он вообще не нужен в рассматриваемом случае.
Пётр, я в программе нашёл пару ошибок и с ними тоже самое было, убрал семафор и оставил только мьютекс и вроде всё в порядке.
Global true.b = 1 ; переменная для вычного цикла
Global mutex = CreateMutex() ; объявление мьютекса
Structure messagebox
sender.l ; номер потока, который отправляет сообщение
recipient.l ; номер потока, которому нужно отпарвить сообщение
message_body.s ; само сообщение
EndStructure
Global NewList queue.messagebox() ; объявление списка queue, в который записываются сообщения
Procedure send(sender_thread.l, recipient_thread.l, message.s)
; send - посылает сообщение заданному потоку
; sender_thread - какой поток отсылает сообщение
; recipient_thread - какому потоку отослать сообщение
; message - само сообщение
LastElement(queue()) ; переходим к последнему элементу в списке
AddElement(queue()) ; добавить новый элемент в список
queue()\sender = sender_thread ; пишем какой поток хочет отослать
queue()\recipient = recipient_thread ; пишем какому потоку хотим отправить сообщение
queue()\message_body = message ; само сообщение
EndProcedure
Procedure.s receive(recipient_message.l)
; receive - получет сообщение от другого потока
; recipient_message - номер потока, который хочет получить сообщение
message.s = "" ; переменная для записи всех сообщений, которые пришли данному потоку
ForEach queue() ; перебираем все сообщения в списке
If queue()\recipient = recipient_message ; если это сообщение направлено данному потоку
; записываем сообщение (далее - все сообщения, которые были отосланы этому потоку)
message = message + "поток " + Str(recipient_message) + " принял: " + queue()\message_body + " от потока " + Str(queue()\sender) + "; "
DeleteElement(queue()) ; Удаление текущего сообщения из списка
EndIf
Next
ProcedureReturn message.s
EndProcedure
Procedure Thread(*number) ; код отдельного потока (всего их 4)
counter.i = 0 ; переменная для данных (их отображение)
While true = 1
Delay(1000)
send_of_receive.l = Random(1) ; поток узнаёт, отправить ли сообщение (1), или принять (0)
If send_of_receive = 1 ; если 1, значит отослать
LockMutex(mutex) ; входим в критическую секцию, с помощью мьютекса
While true = 1 ; в цикле поток узнаёт, какому потоку отправить сообщение
send_thread.l = Random(3) ; но поток не может послать сам себе сообщение
If Not send_thread = *number
Break
EndIf
Wend
data_message.s = "message" + Str(counter) ; формируем сообщение для отправки
counter = counter + 1 ; увеличиваем значение переменной, чтобы различать сообщения
send(*number, send_thread.l, data_message.s) ; отправить сообщение указанному потоку
UnlockMutex(mutex) ; выходим из критической секции, с помощью мьютекса
Else ; иначе получаем сообщение
LockMutex(mutex) ; входим в критическую секцию, с помощью мьютекса
received_message.s = receive(*number) ; получаем сообщения
If Not received_message = "" ; если этому потоку ни кто сообщения не посылал, то ничего и не выводим
Debug received_message
EndIf
UnlockMutex(mutex) ; выходим из критической секции, с помощью мьютекса
EndIf
Wend
EndProcedure
thread0 = CreateThread(@Thread(), 0) ; создать поток thread0
thread1 = CreateThread(@Thread(), 1) ; создать поток thread1
thread2 = CreateThread(@Thread(), 2) ; создать поток thread2
thread3 = CreateThread(@Thread(), 3) ; создать поток thread3
WaitThread(thread0)
WaitThread(thread1)
WaitThread(thread2)
WaitThread(thread3)А вот какой вариант предпочтительнее, как здесь, потоки пишут, затем один поток считывает все пришедшие к нему сообщения, или же мол поток отсылает сообщение и передаёт после передачи управление потоку получателю (чтобы он его сразу принял)? Да и можно ли передать управление заданному потоку?
Отредактировано goodwen (26.05.2011 16:47:58)
Да и можно ли передать управление заданному потоку?
Они ведь работают независимо друг от друга, разве что останавливать и запускать мьютексами.
Но в данном случае, и так работает.
Пётр, спасибо за помощь.
Приветствую ВАС!
Пожалуйста, помогите понять. Я собрал из 3-х LineXY(x1,y1,x2,y2,Color)
треугольник. Хочу заполнить цветом.
Как пользоваться функцией FillArea(x, y, OutlineColor[,FillColor]).
С уважением, Akiva
Всем привет!
Есть рабочая прога. За загрузку иконки отвечает строчка:
AddSysTrayIcon(25, WindowID(#Window_0), ExtractIcon_(0,ProgramFilename(),0))
Вопрос в следующем: в папке с программой поменял иконку с другим именем, при компеляции не может ее найти.
Переименовываю ее, все нормально. Не подскажите в чем проблема? Не хочется ее переименовывать.
Заранее спасибо!
треугольник. Хочу заполнить цветом.Как пользоваться функцией FillArea
Нужно в x и y указать координаты, лежащие внутри треугольника.
If OpenWindow(0, 0, 0, 200, 200, "2DDrawing Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
If CreateImage(0, 200, 200) And StartDrawing(ImageOutput(0))
Box(0, 0, 200, 200, RGB(255, 255, 255))
LineXY(20, 150, 100, 10, 0)
LineXY(180, 150, 100, 10, 0)
LineXY(20, 150, 180, 150, 0)
FillArea(30, 140, -1 , RGB(254, 0, 0))
StopDrawing()
ImageGadget(0, 0, 0, 200, 200, ImageID(0))
EndIf
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
EndIfЕсть рабочая прога. За загрузку иконки отвечает строчка:
В данном случае, используется иконка исполняемого файла.
Она заменяется в свойствах проекта в поле "Использовать иконку".
Пётр, спасибо! Оно самое.
Не подскажете как определить объем диска С? Не свободную память, а общий объем! Заранее спасибо!
Не свободную память, а общий объем!
Какая разница? Определяется одинаково, только выбирай информацию, которая нужна:
Define.q free_bytes_avail, total_bytes, total_free_bytes
If (GetDiskFreeSpaceEx_("C:", @free_bytes_avail, @total_bytes, @total_free_bytes))
Debug "Общий размер в байтах " + Str(total_bytes >> 20*1024)
EndIfОтредактировано ВиниПур (31.05.2011 06:07:22)
Всем привет!
Можно ли как-то сделать многовкладочное меню, как на картинке у Петра в 521 посту?
Спасибо.
Отредактировано max (31.05.2011 09:36:28)
max
Пример из справки
If OpenWindow(0, 0, 0, 322, 220, "PanelGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
PanelGadget (0, 8, 8, 306, 203)
AddGadgetItem (0, -1, "Panel 1")
PanelGadget (1, 5, 5, 290, 166)
AddGadgetItem(1, -1, "Sub-Panel 1")
AddGadgetItem(1, -1, "Sub-Panel 2")
AddGadgetItem(1, -1, "Sub-Panel 3")
CloseGadgetList()
AddGadgetItem (0, -1,"Panel 2")
ButtonGadget(2, 10, 15, 80, 24,"Button 1")
ButtonGadget(3, 95, 15, 80, 24,"Button 2")
CloseGadgetList()
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIfПример из справки
Спасибо! Однако справку надо внимательней смотреть.
Где-то встречал здесь как вывести системное время в окне, а сейчас что-то не по глазам.
Ткните пожалуйста.
Спасибо, Петр
Но я так и не понял как определять координаты
лежащие внутри треугольника.
С уважением к Вам. Akiva
Где-то встречал здесь как вывести системное время в окне, а сейчас что-то не по глазам. Ткните пожалуйста.
Как вариант
If OpenWindow(0, 0, 0, 100, 100, "Timer Example", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
TextGadget(0, 30, 30, 80, 20, "")
AddWindowTimer(0, 123, 1000)
Value = 0
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_Timer And EventTimer() = 123
SetGadgetText(0,FormatDate("%hh:%ii:%ss", Date()))
EndIf
Until Event = #PB_Event_CloseWindow
EndIfНо я так и не понял как определять координатылежащие внутри треугольника.
Просто нужно найти точку, лежащую внутри треугольника.
Например, нижняя горизонтальная линия треугольника, находится по игреку в позиции 150 и если найти центр этой линии (в нашем случае это 80 потому что 180 - 20 = 160/2 = 80) и подняться на несколько пикселей вверх этой линии (например 10, тогда позиция будет 150-10=140), то гарантировано будет точка, лежащая внутри треугольника.
If OpenWindow(0, 0, 0, 200, 200, "2DDrawing Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
If CreateImage(0, 200, 200) And StartDrawing(ImageOutput(0))
Box(0, 0, 200, 200, RGB(255, 255, 255))
LineXY(20, 150, 100, 10, 0)
LineXY(180, 150, 100, 10, 0)
LineXY(20, 150, 180, 150, 0) ; Нижняя горизонтальная линия
FillArea(80, 140, -1 , RGB(254, 0, 0))
StopDrawing()
ImageGadget(0, 0, 0, 200, 200, ImageID(0))
EndIf
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
EndIfКак вариант
Спасибо!
Привет!
Как с помощью библиотеки Droopy или непосредственной работой с реестром удалить программу из автозагрузки?
Нашел.
RunProgramAtStartup(1,1,"Abracadabra","c:\windows\regedit.exe") ; Add to Startup DelProgramAtStartup(1,1,"Abracadabra") ; Remove from Startup
Помнится кто то на нашем форуме хорошо ладил с Delphi. На форуме журнала ПРОграммист наткнулся на интереснейшую тему о определении температуры винта!!! Кто может перекатать на пурик!?!?Вот ссылка
Где-то я видел исходник проги, измеряющий температуру винта, но и где....
Да и давно это было, если найду, выложу.
Привет!
Возникло пару вопросов.
1. Как загрузить текст из директории программы в EditorGadget.
2. Как загрузить текст из любой папки на компе в EditorGadget.
Накидал код и застопорился. Код прилагается.
Global Text.s
OpenWindow(0, 0, 0, 350, 160, "122", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered|#PB_Window_MaximizeGadget)
PanelGadget (0, 5, 5, 340, 150)
AddGadgetItem (0, -1, "1")
AddGadgetItem (0, -1,"2")
AddGadgetItem (0, -1,"3")
AddGadgetItem (0, -1,"4")
AddGadgetItem (0, -1,"5")
AddGadgetItem (0, -1,"Текст")
ComboBoxGadget(48, 154, 98, 163, 21)
EditorGadget(49,154,7,163,89,#PB_Editor_ReadOnly)
ButtonGadget(50,6,6,144,23,"Загрузить текст")
;Получает полный путь запущенного приложения
Result$ = ProgramFilename()
;Извлекает путь из полного пути. Например, если полный путь "C:\PureBasic\PB.exe", результат будет "C:\PureBasic\".
Path$ = GetPathPart(Result$)
;Debug Path$
; Просмотр всех элементов директории запущенного приложения (без поддиректорий)
Directory$ = Path$
If ExamineDirectory(0, Directory$, "*.txt")
m=0
While NextDirectoryEntry(0)
AddGadgetItem(48, -1, Left(DirectoryEntryName(0), Len(DirectoryEntryName(0))-4))
txt.s=Text + ".txt"
If DirectoryEntryName(0) = txt
SetGadgetState(48, m)
EndIf
m=m+1 ;Debug DirectoryEntryName(0) ;+ Type$ + "- Size in byte: " + Str(DirectoryEntrySize(0))
Wend
FinishDirectory(0)
EndIf
CloseGadgetList()
Repeat
Event= WaitWindowEvent()
Window=EventWindow()
Gadget=EventGadget()
If Event=#PB_Event_Gadget
Select EventGadget()
Case 50
StandardFile$ = "" ; set initial file+path to display
; With next string we will set the search patterns ("|" as separator) for file displaying:
; 1st: "Text (*.txt)" as name, ".txt" and ".bat" as allowed extension
; 2nd: "PureBasic (*.pb)" as name, ".pb" as allowed extension
; 3rd: "All files (*.*) as name, "*.*" as allowed extension, valid for all files
Pattern$ = "Text (*.txt)|*.txt"
Pattern = 0 ; use the first of the three possible patterns as standard
File$ = OpenFileRequester("Открыть файл", StandardFile$, Pattern$, Pattern)
If File$
Debug File$
EndIf
EndSelect
EndIf
Until WaitWindowEvent() = #PB_Event_CloseWindowПривет!Возникло пару вопросов.1. Как загрузить текст из директории программы в EditorGadget.2. Как загрузить текст из любой папки на компе в EditorGadget.Накидал код и застопорился. Код прилагается.
;{- Enumerations / DataSections
;{ Windows
Enumeration
#Window_0
EndEnumeration
;}
;{ Gadgets
Enumeration
#Editor_1
#Button_2
EndEnumeration
;}
Define.l Event, EventWindow, EventGadget, EventType, EventMenu
;}
Procedure OpenWindow_Window_0()
If OpenWindow(#Window_0, 455, 62, 400, 400, "Window_0", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
EditorGadget(#Editor_1, 20, 85, 345, 210)
ButtonGadget(#Button_2, 35, 15, 75, 30, "Gadget_2")
EndIf
EndProcedure
OpenWindow_Window_0()
;{- Event loop
Repeat
Event = WaitWindowEvent()
Select Event
; ///////////////////
Case #PB_Event_Gadget
EventGadget = EventGadget()
EventType = EventType()
If EventGadget = #Editor_1
ElseIf EventGadget = #Button_2
File$ = OpenFileRequester("","C:/","Text (*.txt)|*.txt;*.bat|PureBasic (*.pb)|*.pb|All files (*.*)|*.*",0)
If File$
If ReadFile(0, File$)
Size = Lof(0)
*Text = AllocateMemory(Size)
If *Text
ReadData(0, *Text, Size)
EndIf
CloseFile(0)
SetGadgetText(#Editor_1,PeekS(*Text))
EndIf
EndIf
EndIf
; ////////////////////////
Case #PB_Event_CloseWindow
EventWindow = EventWindow()
If EventWindow = #Window_0
CloseWindow(#Window_0)
Break
EndIf
EndSelect
ForEver
;
;}Отредактировано Дмитрий (02.06.2011 18:46:21)
Спасибо!
Не совсем то, что нужно. Поэтому вопрос открыт.
Не совсем то, что нужно. Поэтому вопрос открыт.
что конкретно нужно!?
| Какая версия? | OffTop | 03.10.2021 |
| Мне постоянно пищет вот это | Вопросы по PureBasic | 14.10.2011 |
| Размер экрана в пикселях | Вопросы по PureBasic | 13.02.2011 |
| консоль | Вопросы по PureBasic | 19.03.2015 |
| Полноэкранные приложения на purebasic | Вопросы по PureBasic | 08.03.2011 |
Вы здесь » PureBasic - форум » Вопросы по PureBasic » Вопросы новичка (продолжение…)