15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Классы синхронизации С++ в Win32 и Solaris 2.x

Класс Mutex

  Так выглядит реализация этого класса в Win32
class Mutex {
 private:
   CRITICAL_SECTION lock;

 public:
   Mutex(void) { InitializeCriticalSection(&lock); }
   void Lock(void) { EnterCriticalSection(&lock); }
   void Unlock(void) { LeaveCriticalSection(&lock); }
}; 
  А так класс Mutex выглядит для Solaris 2.x
class Mutex {
 private:
   mutex_t structure_lock;   // structure access lock
   mutex_t lock;             // mutex
   thread_t owner;           // owner of mutex
   unsigned int count;       // # of times owner locked mutex

 public:
   Mutex(void) { 
          mutex_init(&structure_lock, USYNC_THREAD, (void*)0);
          mutex_init(&lock, USYNC_THREAD, (void*)0);
   }

   ~Mutex(void) {
          mutex_destroy(&structure_lock);
          mutex_destroy(&lock);
   }

   void Lock(void) {
          mutex_lock(&structure_lock);
          if (owner == thr_self()) {   // this thread already owns the lock
             count++;
             mutex_unlock(&structure_lock);
          }
          else { 
             // try to obtain the mutex. if we cannot do so immediately, release 
             // the structure lock and wait on the mutex.
             if (mytex_trylock(&lock) != 0) {
                  mutex_unlock(&structure_lock);
                  mutex_lock(&lock);
                  mutex_lock(&structure_lock);
                  owner = thr_self();
             }
             mutex_unlock(&structure_lock);
          }
   }

   void Unlock(void) {
          mutex_lock(&structure_lock);
          if ((owner == thr_self()) && (--count == 0)) 
                  mutex_unlock(&lock);
          mutex_unlock(&structure_lock);
   }
}; 
  А это примерчик использования класса Mutex
class SafeInteger : private Mutex {
 private:
   int value;

 public:
   void SetValue(int new_value) {
          Lock();
          value = new_value;
          Unlock();
   }

   int GetValue(void) {
          Lock();
          int ret_value = value;
          Unlock();
          return ret_value;
   }
}; 

Класс Semaphore

  Так выглядит реализация класса Semaphore в Win32
class Semaphore {
 private:
    HANDLE semaphore;

 public:
    Semaphore(void) {
             CreateSemaphore((void *)0, 0, 0x7ffffff, (void*)0);
    }

    Semaphore(int available) {
             CreateSemaphore((void *)0, available, 0x7ffffff, (void*)0);
    }

    ~Semaphore(void) {
                CloseHandle(semaphore);
    }

    void Wait(void) {
                WaitForSingleObject(semaphore, INFINITE);
    }

    void Post(void) {
                ReleaseSemaphore(semaphore, 1, (void*)0);
    }

    void Post(int how_many) {
                ReleaseSemaphore(semaphore, how_many, (void*)0);
    }
}; 
  А так класс Semaphore выглядит для Solaris 2.x
class Semaphore {
 private:
    sema_t semaphore;

 public:
    Semaphore(void) {
              sema_init(&semaphore, 0, USYNC_PROCESS, (void*)0);
    }

    Semaphore(int available) {
            sema_init(&semaphore, available, USYNC_PROCESS, (void*)0);
    }

    ~Semaphore(void) {
            sema_destroy(&semaphore);
    }

    void Post(void) {
           sema_post(&semaphore);
    }

    void Post(int how_many) {
            while (how_many-- 0) sema_post(&semaphore);
    }

    void Wait(void) {
            sema_wait(&semaphore);
    }
}; 
  А это примерчик использования класса Semaphore
template class QueueEntry : public T {
    public:
          T value;
          QueueEntry* next;

          QueueEntry(const T& item_value) {
                 value = item_value;
                 next = (QueueEntry*)0;
         }
};

template class Queue : private Semaphore : private Mutex {
    private:
           QueueEntry* head;
           QueueEntry* tail;

    public:
           Queue(void) {
                   head = tail = (QueueEntry*)0;
          }

          void Add(const T& item_value) {
                   Lock();
                   if (tail == QueueEntry*)0)
                                  head = tail = new QueueEntry(item_value);
                   else {
                                  tail-next = new QueueEntry(item_value);
                                  tail = tail-next;
                   }
                   Unlock();
                   Post(); // wake up any waiting threads
        }

        T Wait(void) {
                   Semaphore::Wait(); // wait for something to show up
                   Lock();
                   T value = head-value;
                   QueueEntry* old = head;
                   head = head-next;
                   delete old;
                   if (head == (QueueEntry*)0)
                               tail = (QueueEntry*)0;
                   Unlock();
                   return value;
        }
};

Класс Event

  Так выглядит реализация класса Event в Win32
class Event {
 private:
   HANDLE event;

 public:
   Event(void) {
       event = CreateEvent((void*)0, TRUE, FALSE, (void)0);
   }

   ~Event(void) {
       CloseHandle(event);
   }

   void Signal(void) {
       PulseEvent(event);
   }

   void Wait(void) {
       WaitForSingleObject(event, INFINITE);
   }
}; 
  А так класс Event выглядит для Solaris 2.x
class Event {
 private:
   cond_t event;

   // in order to wait on a condition variable you must have a locked
   // mutex, which we don't really need.
   mutex_t dummy_mutex;

 public:
   Event(void) {
        cond_init(&event, USYNC_PROCESS, (void*)0);
        mutex_init(&dummy_mutex, USYNC_PROCESS, (void*)0);
   }

   ~Event(void) {
        event_destroy(&event);
   }

   void Signal(void) {
        cond_broadcast(&event);
   }

   void Wait(void) {
        mutex_lock(&dummy_mutex);
        cond_wait(&event, &dummy_mutex);
        mutex_unlock(&dummy_mutex);
   }
};