Author: Vincent Diepeveen
Date: 15:40:04 04/25/01
Go up one level in this thread
On April 25, 2001 at 17:34:59, Hristo wrote: >Following is a code that you can use for locking >and or signaling stuff in linux. >This is the same as WaitForSingleObject ... > >Example: >// create a locked semaphore >// with maximum of 1 lock (non counting) >CSISemaphore g_sem(0,1); >void thread_func(){ > while (1){ > // do something > > // signal the semaphore that we are done > // you can unlock it any number of times ... > // it is not counting semaphore so nothing bad happens > g_sem.unlock(); > } >} > >// >// > >int main(){ > start_my_thread(thread_func); > > while(1){ > // wait 100 ms for the semaphore to get signaled (unlocked) > if (g_sem.lock(100)){ > cout << "The semaphore was signaled..." << endl; > break; /// .... > }else{ > cout << "." << flush; > } > } > return 0; >} > > >This is the actual header and source stuff that you need. >best regards. Many thanks. I don't see how it works, sorry to bother you again! I do not want to waste 100ms of time for threads. in my main i'm doing actually not only starting threads but also other processes. Basically those other processes i want to idle: P1.Main() { allocate shared memory; start other searchprocesses P2..P4; start i/o thread thisprocessnumber = P1; Search(); } .. iothread() { for(;;) {// this thread doing i/o for all processes now wait for keyboard input and idle when waiting for it; parse_keyboard_input(); if( relevantkeyboardinput ) { /* so i start to search */ // now somehow wakup P1..Pn. what i do now is, is to give it sharedtree->gosearch = true; } } } /* now one example is other search */ P2.Search() { /* in main already initialized and synchronized with P1 */ idle till you get go command and don't waste 100ms or whatever before receiving it as it must wake up DIRECTLY } In short the interesting thing is what to do for P1() to message both a thread in the own process to start searching and to also message other processes to start searching. Bob says i should use Select there somehow, with what function do i message this function? With signal? Note locking/unlocking i'll manage myself. i've pretty much learned to work with locking/unlocking but not with idling yet :) So interesting to know is how to wait for keyboard input without wasting system time while waiting and what function to use to message Select in other processes (and one in the own process) that it must wake up. So please read carefully other PROCESSES not threads!! It's especially the IPC that worries me :) >hristo > > >--- header file --- >/** > * General purpose semaphore interface > * Under unix there we are using mutex and > * conditional variable to provide lock with > * timeout. Since the lock with timeout is > * not supported natively by the OS there are > * some special issues that might occur. For > * instance if the timeout value is not large > * enough the thread might never accuire the > * lock. > * > * @author Hristo Doichev > * @version 0.1 > */ >class CSISemaphore{ > public: > /** > * create a single semaphore. > * > * @param _initial determines the initial state of the semaphore. > * 0 the semaphore is created and locked immediately. > * 1 the semaphore is not locked within the constructor. > * @return > */ > explicit CSISemaphore(unsigned int _initial); > /** > * create a counting Semaphore. > * > * @param _initial determines the amount of locks that can be applied to >this semaphore > * after the cnstruction. > * 0 the semaphore is completely locked. > * n <= _max is the number of loks that can be applied > * @param _max the maximum number of locks this semaphore can take > * > * @return > */ > explicit CSISemaphore(unsigned int _initial, unsigned int _max); > virtual ~CSISemaphore(); > > virtual bool check(); > virtual void lock(); > virtual void unlock(); > > virtual bool lock(unsigned int _time_out); > private: > pthread_mutex_t m_mut; > pthread_cond_t m_con; > int m_con_var; > int m_max_locks; >}; > >--- source --- > > >#include THE_HEADER_FILE_ABOVE >#include <errno.h> >#include <unistd.h> >#include <sys/time.h> >#include <iostream> > >#define CSI_PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP {0, 0, 0, >PTHREAD_MUTEX_RECURSIVE_NP, {0, 0}} > > >/** purpose: create a single lock semaphore >*/ >CSISemaphore::CSISemaphore(unsigned int >_initial):m_con_var(_initial),m_max_locks(1) >{ > m_mut.__m_count = 0; > m_mut.__m_lock.__spinlock = 0; > m_mut.__m_lock.__status = 0; > m_mut.__m_owner = 0; > m_mut.__m_reserved = 0; > m_mut.__m_kind = PTHREAD_MUTEX_RECURSIVE_NP; > //m_mut = {0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, {0, 0}}; > pthread_mutex_init(&m_mut, 0); > pthread_cond_init(&m_con, 0); >} >/** purpose: create a counting Semaphore >*/ >CSISemaphore::CSISemaphore(unsigned int _initial, unsigned int >_max):m_con_var(_initial),m_max_locks(_max) >{ > m_mut.__m_count = 0; > m_mut.__m_lock.__spinlock = 0; > m_mut.__m_lock.__status = 0; > m_mut.__m_owner = 0; > m_mut.__m_reserved = 0; > m_mut.__m_kind = PTHREAD_MUTEX_RECURSIVE_NP; > //m_mut = {0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, {0, 0}}; > pthread_mutex_init(&m_mut, 0); > pthread_cond_init(&m_con, 0); > if (m_con_var > m_max_locks) { > m_con_var = m_max_locks; > } >} >/** >*/ >CSISemaphore::~CSISemaphore(){ > pthread_mutex_destroy(&m_mut); > pthread_cond_destroy(&m_con); >} >/** >*/ >bool CSISemaphore::check(){ > bool is_not_locked; > pthread_mutex_lock(&m_mut); > if (m_con_var > 0) { > is_not_locked = true; > }else{ > is_not_locked = false; > } > pthread_mutex_unlock(&m_mut); > return is_not_locked; >} >/** >*/ >void CSISemaphore::lock(void){ > pthread_mutex_lock(&m_mut); > if (m_con_var == 0) { > do { > pthread_cond_wait(&m_con, &m_mut); > } while ( m_con_var == 0); > } > --m_con_var;// = 0; > pthread_mutex_unlock(&m_mut); >} >/** >*/ >void CSISemaphore::unlock(void){ > pthread_mutex_lock(&m_mut); > ++m_con_var;// = 1; > if (m_con_var > m_max_locks) { > m_con_var = m_max_locks; > } > pthread_mutex_unlock(&m_mut); > pthread_cond_signal(&m_con); > //sched_yield(); >} >/** >* This is perhaps the most complicatied of all sync functions. >* The general unix pthread library does not support timeouts on >* mutexes and therefore we need to use conditional variables. >* However, the conditional variables do not guarantee smooth >* execution. There are many conditions which can cause problems. >* >* _time_out in ms >*/ >bool CSISemaphore::lock(unsigned int _time_out){ > bool got_a_lock = false; > unsigned int status = 0; > struct timespec timeout; > struct timeval start_time; > // lock the mutex so we can check the predicate > pthread_mutex_lock(&m_mut); > // if someone has the predicate the wait on the condition variable >TRY_TO_WAIT: > if (m_con_var == 0) { > gettimeofday(&start_time,0); > //cout << " sec: " << start_time.tv_sec << ", usec: " << >start_time.tv_usec << endl; > unsigned int sec_delta = _time_out/1000; > timeout.tv_sec = start_time.tv_sec + (sec_delta); > timeout.tv_nsec = start_time.tv_usec + >(_time_out-(sec_delta*1000))*100000; > //cout << "> sec: " << timeout.tv_sec << ", usec: " << timeout.tv_nsec ><< endl; > status = pthread_cond_timedwait(&m_con, &m_mut, &timeout); > } > if (m_con_var > 0) { > --m_con_var;// = 0; > got_a_lock = true; > }else{ > if (status == ETIMEDOUT) { > got_a_lock = false; > cout << "timed wait status:" << status << endl; > }else{ > unsigned int temp_time = (time(0) - timeout.tv_sec); > if ((_time_out/1000) > temp_time ) { > _time_out -= (temp_time*1000); > cout << ">> retry lock( " << _time_out << " )" << endl; > goto TRY_TO_WAIT; > } > } > } > > // unlock the mutex so others can do their job (and wait) > pthread_mutex_unlock(&m_mut); > return got_a_lock; >}
This page took 0 seconds to execute
Last modified: Thu, 15 Apr 21 08:11:13 -0700
Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.