в чём может быть проблема
Может быть в том, что все потоки ждут сообщения, а не отсылают его.
Ведь такая ситуация может произойти.
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 » Вопросы новичка (продолжение…)