Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Работа с потоками, Согласование потоков 
:(
    Опции темы
JackYF
  Дата 11.10.2004, 00:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Кто работал с потоками?
Как выполнить их согласование?

Проблема такая: два потока должны обращаться к форме (С++ Builder 6).
Всё вроде нормально в отладке, но при реальной работе возникает куча глюков в плане перемещения объектов по всей форме с недопрорисовкой.

Что делать? что-то вообще можно сделать?

Попутно вопрос - можно ли устранить мелькание RichTextBox во время работы с ним?

Потоки вызываю CreateThread'ом.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
<Spawn>
Дата 11.10.2004, 05:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Око кары:)
****


Профиль
Группа: Экс. модератор
Сообщений: 2776
Регистрация: 29.1.2003
Где: Екатеринбург

Репутация: нет
Всего: 64



Используй метод Synchronize


--------------------
"Для некоторых людей программирование является такой же внутренней потребностью, подобно тому, как коровы дают молоко, или писатели стремятся писать" - Николай Безруков.
PM MAIL ICQ   Вверх
VID
Дата 11.10.2004, 05:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 57
Регистрация: 4.10.2004
Где: Новосибирск

Репутация: нет
Всего: нет



Очень интересным представляется компонент BMThread разработанный Boian Mitov специально для работы с потоками (C++Builder4, 5, 6). Чтоб понять как работает, достаточно посмотреть example. Если надо могу прислать исходники - давайте mail please smile.gif
PM MAIL   Вверх
JackYF
Дата 11.10.2004, 23:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Ну, что ж, давай VID - [email protected]


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
JackYF
Дата 11.10.2004, 23:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



<Spawn>, что за Synchronize?


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
_hunter
Дата 12.10.2004, 10:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 16
Всего: 98



берем HELP и в нем видим:
Цитата

When you use objects from the VCL or CLX object hierarchies, their properties and methods are not guaranteed to be thread-safe. That is, accessing properties or executing methods may perform some actions that use memory which is not protected from the actions of other threads. Because of this, a main thread is set aside to access VCL and CLX objects. This is the thread that handles all Windows messages received by components in your application.
If all objects access their properties and execute their methods within this single thread, you need not worry about your objects interfering with each other. To use the main thread, create a separate routine that performs the required actions. Call this separate routine from within your thread’s Synchronize method. For example:

void __fastcallTMyThread::PushTheButton(void)

{
  Button1->Click();
}
void __fastcallTMyThread::Execute()
{
  ...
  Synchronize((TThreadMethod)PushTheButton);
  ...
}

Synchronize waits for the main thread to enter the message loop and then executes the passed method.

Note: Because Synchronize uses the message loop, it does not work in console applications. You must use other mechanisms, such as critical sections, to protect access to VCL or CLX objects in console applications.

You do not always need to use the main thread. Some objects are thread-aware. Omitting the use of the Synchronize method when you know an object’s methods are thread-safe will improve performance because you don’t need to wait for the VCL or CLX thread to enter its message loop. You do not need to use the Synchronize method for the following objects:

Data access components are thread-safe as follows: For BDE-enabled datasets, each thread must have its own database session component. The one exception to this is when you are using Microsoft Access drivers, which are built using a Microsoft library that is not thread-safe. For dbDirect, as long as the vendor client library is thread-safe, the dbDirect components will be thread-safe. ADO and InterbaseExpress components are thread-safe.

When using data access components, you must still wrap all calls that involve data-aware controls in the Synchronize method. Thus, for example, you need to synchronize calls that link a data control to a dataset by setting the DataSet property of the data source object, but you don’t need to synchronize to access the data in a field of the dataset.
For more information about using database sessions with threads in BDE-enabled applications, see Managing multiple sessions.

DataCLX objects are thread-safe although VisualCLX objects are not.
Graphics objects are thread-safe. You do not need to use the main VCL or CLX thread to access TFont, TPen, TBrush, TBitmap
, TMetafile (VCL only), TDrawing (CLX only), or TIcon. Canvas objects can be used outside the Synchronize method by locking them.

While list objects are not thread-safe, you can use a thread-safe version, TThreadList, instead of TList.

Call the CheckSynchronize routine periodically within the main thread of your application so that background threads can synchronize their execution with the main thread. The best place to call CheckSynchronize is when the application is idle (for example, from an OnIdle event handler). This ensures that it is safe to make method calls in the background thread.



--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
VID
Дата 12.10.2004, 21:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 57
Регистрация: 4.10.2004
Где: Новосибирск

Репутация: нет
Всего: нет



JackYF лови на мыло

PM MAIL   Вверх
bel_nikita
Дата 12.10.2004, 22:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



Не знаю, наверное, не в тему, но может пригодиться такой наборчик классов smile.gif
Код
namespace KernelLib {

 class cEvent
 {
 public:
     cEvent (bool manualReset = false)
     {
         // start in non-signaled state (red light)
         _handle = CreateEvent (0, manualReset, FALSE, 0);
     }
     ~cEvent ()
     {
         CloseHandle (_handle);
     }

     // put into signaled state
     void Release () {
   SetEvent (_handle);
  }
  void SetSignaled () {
   SetEvent (_handle);
  }
  /* if it's event with manual reset*/
  void SetNonSignaled () {
   ResetEvent (_handle);
  }
  HANDLE H() {
   return _handle;
  }
     bool Wait (DWORD milliseconds) {
         return (WaitForSingleObject(_handle, milliseconds) == WAIT_OBJECT_0);
     }
 private:
     HANDLE _handle;
 };

 //class for simple use critical section
 class cCriticalSection
 {
 public:
    cCriticalSection();
    ~cCriticalSection();
    void lock ();
    void unlock();
    CRITICAL_SECTION _critSection;
 };

 //class critical section
 inline cCriticalSection::cCriticalSection()
 {
   InitializeCriticalSection (&_critSection);
 }
 inline cCriticalSection::~cCriticalSection()
 {
   DeleteCriticalSection (&_critSection);
 }
 inline void cCriticalSection::lock()
 {
  EnterCriticalSection (&_critSection);
 }
 inline void cCriticalSection::unlock()
 {
  LeaveCriticalSection(&_critSection);
 }

 //class for simple use mutex
 class cMutex
 {
 public:
  cMutex();
  ~cMutex();
  void lock();
  void unlock();
 private:
  HANDLE mutex;
 
 };
 //class mutex
 inline cMutex::cMutex()
 {
  mutex = CreateMutex(NULL,FALSE,NULL);
  // if (mutex == NULL){assert(1);}  
 }
 inline cMutex::~cMutex()
 {
  CloseHandle(mutex);
 }
 inline void cMutex::lock()
 {
  WaitForSingleObject(mutex,INFINITE);
 }
 inline void cMutex::unlock()
 {
  ReleaseMutex(mutex);
 }

 class cFastEvent
 {
 public:
     cFastEvent ()
     {
         // start in non-signaled state (red light)
         // auto reset after every Wait
       _critSect.lock();
     }

     ~cFastEvent ()
     {
       _critSect.unlock();
     }
     // put into signaled state
     void Release () { _critSect.unlock(); }
     void Wait ()
     {
         // Wait until event is in signaled (green) state
         _critSect.lock();
     }
     operator cCriticalSection () { return _critSect; }
 private:
   cCriticalSection _critSect;
     HANDLE _handle;
 };

 class cEvents
 {
 public:
     cEvents ()
     {
         // start in non-signaled state (red light)
         // auto reset after every Wait
         _handle = CreateEvent (0, FALSE, FALSE, 0);
     }

     ~cEvents ()
     {
         CloseHandle (_handle);
     }

     // put into signaled state
     void Release () { SetEvent (_handle); }
     void Wait ()
     {
         // Wait until event is in signaled (green) state
         WaitForSingleObject(_handle, INFINITE);
     }
     operator HANDLE () { return _handle; }
 private:

     HANDLE _handle;
 };

 class cTrafficLight
 {
 public:
     cTrafficLight ()
     {
         // Start in non-signaled state (red light)
         // Manual reset
         _handle = CreateEvent (0, TRUE, FALSE, 0);
     }

     ~cTrafficLight ()
     {
         CloseHandle (_handle);
     }

     // put into signaled state
     void GreenLight () { SetEvent (_handle); }

     // put into non-signaled state
     void RedLight () { ResetEvent (_handle); }

     void Wait ()
     {
         // Wait until event is in signaled (green) state
         WaitForSingleObject(_handle, INFINITE);
     }

 private:
     HANDLE _handle;
 };
 //
 //TODO: semaphore object, thread object, active object
 //

 class Thread
 {
 public:
     Thread ( DWORD (WINAPI * pFun) (void* arg), void* pArg)
     {
         _handle = CreateThread (
             0, // Security attributes
             0, // Stack size
             pFun,
             pArg,
             CREATE_SUSPENDED,
             &_tid);
     }
     ~Thread () { CloseHandle (_handle); }
     void SetPriority(int nPriority){
 #ifndef WINPLATFORM
   SetThreadPriority(_handle,nPriority);
 #endif
  }
     void Resume () { ResumeThread (_handle); }
     void Suspend() { SuspendThread(_handle); }
     void WaitForDeath ()
     {
         WaitForSingleObject (_handle, 2000);
     }
     HANDLE GetHandle() { return _handle; }
  DWORD GetID() {return _tid; }
 private:
     HANDLE _handle;
     DWORD  _tid;     // thread id
 };


 class cActiveObject
 {
 public:
     cActiveObject ();
     virtual ~cActiveObject () {}
     void Kill ();
     void SetPriority(int nPriority){_thread.SetPriority(nPriority);}
 protected:
     virtual void InitThread () {};
     virtual void Loop () = 0;
     virtual void FlushThread () {};

     static DWORD WINAPI ThreadEntry (void *pArg);

     int             _isDying;
     Thread          _thread;
 };


 // The constructor of the derived class
 // should call
 //    _thread.Resume ();
 // at the end of construction

 inline cActiveObject::cActiveObject ():_isDying (0),
   #pragma warning(disable: 4355) // 'this' used before initialized
    _thread (ThreadEntry, this)
   #pragma warning(default: 4355)
 {
 }
 inline void cActiveObject::Kill ()
 {
     _isDying++;
     FlushThread ();
     // Let's make sure it's gone
     _thread.WaitForDeath ();
 }
 inline DWORD WINAPI cActiveObject::ThreadEntry (void* pArg)
 {
     cActiveObject * pActive = (cActiveObject *) pArg;
     pActive->InitThread ();
     pActive->Loop ();
     return 0;
 }

 /*==================================================
 have functions Stop and Start
 ===================================================*/
 class cAdvancedActiveObject
 {
 public:
     cAdvancedActiveObject ();
     virtual ~cAdvancedActiveObject () { Stop(); }
  virtual bool Start(char *chThreadName = "");
  virtual bool Stop();
  bool Started() { return (_thread != NULL); };
  virtual bool SetPriority(int nPriority);
 protected:
     virtual void InitThread () {};
     virtual void Loop () = 0;
     virtual void FlushThread () {};

     static DWORD WINAPI ThreadEntry (void *pArg);

     int   _isDying;
     Thread * _thread;
 };
 /*
 in derived class's destructor you should call use Stop(), else FlushThread won't be called
 */
 inline cAdvancedActiveObject::cAdvancedActiveObject () {
  _thread = NULL;
 }
 inline bool cAdvancedActiveObject::Start (char *chThreadName) {
  if (_thread)
   return false;
  InitThread();
  _isDying = 0;
  _thread = new Thread(ThreadEntry, this);
  if (!_thread)
   return false;
  _thread->Resume();
 #ifndef WINPLATFORM
 #ifdef PHARLAP
  EtsSetThreadDebugName(_thread->GetHandle(), chThreadName);
 #endif //PHARLAP
 #endif
  return true;
 }
 inline bool cAdvancedActiveObject::Stop () {
  if (!_thread)
   return false;
     _isDying++;
     // Let's make sure it's gone
     _thread->WaitForDeath ();
  delete _thread;
  _thread = NULL;
     FlushThread ();
  return true;
 }
 inline DWORD WINAPI cAdvancedActiveObject::ThreadEntry (void* pArg) {
     cAdvancedActiveObject * p = reinterpret_cast<cAdvancedActiveObject *>(pArg);
     p->Loop ();
     return 0;
 }
 inline bool cAdvancedActiveObject::SetPriority(int nPriority) {
  if (!_thread)
   return false;
  _thread->SetPriority(nPriority);
  return true;
 }
}



--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
JackYF
Дата 13.10.2004, 23:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Спасибо VID, посмотрю в ближайшее время!

__hunter: посмотрим...


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0522 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.