offline
- Peca
- Glavni Administrator
- Predrag Damnjanović
- SysAdmin i programer
- Pridružio: 17 Apr 2003
- Poruke: 23211
- Gde živiš: Niš
|
evo... mojih ruku delo
thread.h :
#ifndef _INCLUDED_PAPI_THREAD_H
#define _INCLUDED_PAPI_THREAD_H 1
#ifdef WIN32
#ifndef _WIN32
#define _WIN32 1
#endif
#endif
#ifdef _WIN32
#define sleep_sec(s) Sleep(s*1000)
#define sleep_millisec(s) Sleep(s)
#else
#include <unistd.h>
#define sleep_sec(s) sleep(s)
#define sleep_millisec(s) usleep(s*1000)
#endif
// #define DONT_USE_BEGINTHREADEX // uncomment this if your compiler does not have _beginthreadex in stdc
#ifdef _WIN32
#ifndef USE_WINAPI_MTF
#include <process.h>
typedef unsigned (__stdcall *PTHREAD_START) (void *);
#endif
#include <windows.h>
#include <limits.h>
#else
#include <pthread.h>
#define INFINITE 0
#endif
namespace papi
{
class critical_section
{
public:
critical_section ();
~critical_section ();
int init (void *mutexattr);
int destroy ();
int enter ();
int try_enter ();
int leave ();
inline int is_free () {return entered;}
#ifdef _WIN32
CRITICAL_SECTION cs;
#else
pthread_mutex_t cs;
#endif
private:
int entered;
};
class thread;
struct thread_arg
{
thread *p;
void *arg1;
void *arg2;
};
class thread
{
public:
thread ();
~thread ();
int create (void *(*function)(void *), void * argument);
int join (int *result);
int attr_init ();
int attr_destroy ();
int attr_setdetachstate(int detachstate);
int exit(int retval=0);
int terminate(int retval=0);
int get_priority() const;
int set_priority (unsigned int priority);
int lock (int ecs=0);
int unlock (int ecs=0);
int semaphore (int ecs=0);
thread_arg arg;
// int id;
int is_live ();
int lock_phase ();
int is_busy ();
void set_busy (int b);
int should_exit ();
void should_exit (int s);
critical_section cs;
private:
int ri;
int live;
int busy;
int need_to_exit;
#ifdef _WIN32
unsigned long tid;
HANDLE pid;
int unlocked;
#else
pthread_t pid;
pthread_attr_t attr;
pthread_cond_t cond;
#endif
int lock_level;
int terminated_signal;
};
};
#endif
thread.cpp :
#include "thread.h"
#include <stdio.h>
namespace papi
{
critical_section :: critical_section ()
{
this->init (NULL);
entered=0;
}
critical_section :: ~critical_section ()
{
this->destroy ();
}
int critical_section :: init (void *mutexattr)
{
#ifdef _WIN32
InitializeCriticalSection(&cs);
return 1;
#else
if ( pthread_mutex_init(&cs, (const pthread_mutexattr_t *)mutexattr) == 0)
return 1;
else
return 0;
#endif
}
int critical_section :: destroy ()
{
#ifdef _WIN32
DeleteCriticalSection(&cs);
return 1;
#else
if ( pthread_mutex_destroy(&cs) == 0)
return 1;
else
return 0;
#endif
}
int critical_section :: try_enter ()
{
#ifdef _WIN32
if (TryEnterCriticalSection(&cs)!=0)
{
entered=1;
return 1;
}
else
return 0;
#else
if (pthread_mutex_trylock(&cs) == 0)
{
entered=1;
return 1;
}
else
return 0;
#endif
}
int critical_section :: enter ()
{
#ifdef _WIN32
EnterCriticalSection(&cs);
entered=1;
return 1;
#else
if (pthread_mutex_lock(&cs) == 0)
{
entered=1;
return 1;
}
else
return 0;
#endif
}
int critical_section :: leave ()
{
#ifdef _WIN32
LeaveCriticalSection(&cs);
entered=0;
return 1;
#else
if (pthread_mutex_unlock(&cs) == 0)
{
entered=0;
return 1;
}
else return 0;
#endif
}
int thread :: lock (int ecs)
{
if (ecs==0) cs.enter();
//printf ("%i: ================== locking :: level = %i\n", id, lock_level);
if (lock_level==0)
{
lock_level=1;
//printf ("%i: ================== locked :: level = %i\n", id, lock_level);
ri=1;
}
else
ri=0;
if (ecs==0) cs.leave();
return ri;
}
int thread :: unlock (int ecs)
{
if (ecs==0) cs.enter();
//printf ("%i: ================== unlocking :: level = %i\n", id, lock_level);
if (lock_level==2)
{
#ifdef _WIN32
unlocked=0;
while (1)
{
ResumeThread (pid);
if (unlocked==1) break;
sleep_millisec(10);
}
#else
pthread_cond_signal (&cond);
#endif
//printf ("%i: ================== unlocked\n", id);
ri=1;
}
else
{
lock_level=0;
ri=0;
}
if (ecs==0) cs.leave();
return ri;
}
int thread :: semaphore (int ecs)
{
if (ecs==0) cs.enter();
//printf ("%i: ================== semaphoring :: level = %i\n", id, lock_level);
if (lock_level==1)
{
lock_level=2;
//printf ("%i: ================== semaphore_begin :: level = %i\n", id, lock_level);
#ifdef _WIN32
cs.leave();
SuspendThread (pid);
unlocked=1;
cs.enter();
#else
pthread_cond_wait (&cond, &cs.cs);
#endif
lock_level=0;
//printf ("%i: ================== semaphore_end :: level = %i\n", id, lock_level);
ri=1;
}
else
ri=0;
if (ecs==0) cs.leave();
return ri;
}
thread :: thread ()
{
#ifdef _WIN32
pid=0;
tid=0;
#else
attr_init ();
pthread_cond_init (&cond, 0);
#endif
live=0;
arg.p=this;
need_to_exit=0;
terminated_signal=0;
// id=-1;
lock_level=0;
busy=0;
}
thread :: ~thread ()
{
#ifdef _WIN32
terminate ();
#else
attr_destroy ();
pthread_cond_destroy (&cond);
#endif
}
int thread :: create (void * (*function)(void *), void * argument)
{
arg.arg1=argument;
#ifdef _WIN32
#ifdef DONT_USE_BEGINTHREADEX
pid = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) function, (void *)&arg, 0, &tid);
#else
pid = (HANDLE)_beginthreadex (NULL, 0, (PTHREAD_START) function, (void *)&arg, 0, (unsigned int *)&tid);
#endif
if (pid!=0)
{
live=1;
set_priority(3);
return 1;
}
else return 0;
#else
ri = pthread_create (&pid, &attr, function, (void *)&arg);
if (ri==0)
{
live=1;
return 1;
}
else
return 0;
#endif
}
int thread :: exit(int retval)
{
terminated_signal=retval;
live=0;
#ifdef _WIN32
if (pid!=0)
{
#ifdef DONT_USE_BEGINTHREADEX
ExitThread(retval);
CloseHandle(pid);
#else
_endthreadex(retval);
ExitThread(retval);
CloseHandle(pid);
#endif
}
#else
pthread_exit ((void *)retval);
#endif
return 1;
}
int thread :: terminate(int retval)
{
terminated_signal=retval;
live=0;
#ifdef _WIN32
if (pid!=0)
{
TerminateThread(pid, retval);
CloseHandle(pid);
return 1;
} else return 0;
#else
pthread_exit ((void *)retval);
return 1;
#endif
}
int thread :: join (int *result)
{
if (live==1)
{
#ifdef _WIN32
ri = WaitForSingleObject (pid, INFINITE);
if (ri == WAIT_FAILED) {*result=0; return 0;}
if (ri == WAIT_TIMEOUT) this->terminate(-1);
live=0;
if (GetExitCodeThread (pid, (DWORD *) result)==TRUE) return 1;
*result=0;
return 0;
#else
void *rv;
ri = pthread_join(pid, &rv);
live=0;
if (ri==0)
{
*result = (int)rv;
return 1;
}
else
{
*result = 0;
return 0;
}
#endif
}
else
{
*result=terminated_signal;
return 0;
}
}
int thread :: attr_init ()
{
#ifndef _WIN32
ri = pthread_attr_init (&attr);
if (ri==0) return 1; else return 0;
#else
return 1;
#endif
}
int thread :: attr_destroy ()
{
#ifndef _WIN32
ri = pthread_attr_destroy (&attr);
if (ri==0) return 1; else return 0;
#else
return 1;
#endif
}
int thread :: attr_setdetachstate (int detachstate)
{
#ifndef _WIN32
ri = pthread_attr_setdetachstate(&attr, detachstate);
if (ri==0) return 1; else return 0;
#else
return 1;
#endif
}
int thread :: get_priority() const
{
#ifdef _WIN32
return GetThreadPriority(pid);
#else
return 3;
#endif
}
int thread :: set_priority(unsigned int priority)
{
#ifdef _WIN32
if(SetThreadPriority(pid, priority)==0)
return 0;
else
return 1;
#else
return 1;
#endif
}
int thread :: is_live ()
{
return live;
}
int thread :: is_busy ()
{
return busy;
}
void thread :: set_busy (int b)
{
busy=b;
}
int thread :: lock_phase ()
{
return lock_level;
}
int thread :: should_exit ()
{
return need_to_exit;
}
void thread :: should_exit (int s)
{
need_to_exit=s;
}
};
PAPI je skracenica od Peca's API
primer.cpp
#include <stdio.h>
#include "thread.h"
void *thread_function (void *arg)
{
papi::thread_arg *args = (papi::thread_arg *) arg;
papi::thread *t = args -> p;
int tid = (int)args->arg1;
printf ("Hi from thread : %i\n", tid);
printf ("Sleeping...\n");
t->lock();
t->semaphore();
printf ("-------------------------- Exiting !!!!!!!!!!!!! -----------\n");
t -> exit (1);
}
int main(int argc, char **argv)
{
papi::thread t;
int r;
t.create (thread_function, (void *)1);
sleep_sec(2);
t.unlock();
t.join (&r);
printf ("Returned: %i\n", r);
return 0;
}
primer kreira jednu nit, koja samu sebe odmah zakljuca, a glavna nit spava dve sekunde, otkljuca kreiranu nit, saceka da se nit ugasi, i odstampa rezultat koji joj je ugasena nit prosledila.
|