This is MultiThread plugin. And I don't know what to write hereAttention:. Examples speak for themselves.
http://en.wikipedia.org/wiki/Multith...rchitecture%29
PAWN is not designed to be multi-threaded and there are no guarantees AT ALL on your data the moment you introduce threads. |
Wrong using this plugin can significantly corrupt your gamemode.How to use:
#include <thread>
- Added new native CreateThreadEx( const pubname[ ] );
- First release.
native CreateThread( const pubname[ ] );
native CreateThreadEx( const pubname[ ] );
native DestroyThread( threadid );
native SleepThread( milliseconds ); // Use in thread (public)
native LockThread( threadid ); // Synchronize will return the id lock
native UnLockThread( lockid );
With CreateThread
new tickid;
public OnGameModeInit()
{
tickid = CreateThread( "MyFunction" );
}
public OnGameModeExit()
{
DestroyThread( tickid );
}
public MyFunction( threadid )
{
printf( "tick(%d)...", threadid );
SleepThread( 1000 );
}
With CreateThreadEx
new bool:active;
new tickid;
public OnGameModeInit()
{
tickid = CreateThreadEx( "MyFunction" );
}
public OnGameModeExit()
{
active = false;
}
public MyFunction( threadid )
{
active = true;
while ( active )
{
printf( "tick(%d)...", threadid );
SleepThread( 1000 );
}
}
Thread(.inc + .dll + .so)
Thread Source
Thread(.inc + .dll + .so)
Thread Source
Thread Example(server time and object sreamer in thread)
I'm confused about what this dose, is it just a different way to call a function?
|
http://en.wikipedia.org/wiki/Multith...rchitecture%29
If you speak Russian, i can explain it to you =))) |
will get in handy for ....pro scripter.....not a beginner like me.....
![]() |
new bool:active; new tickid; public OnGameModeInit() { tickid = ThreadCreate( "MyFunction" ); } public OnGameModeExit() { active = false; } public MyFunction() { active = true; while ( active ) { printf( "tick..." ); SleepThread( 1000 ); } } public onThreadDeath( threadid ) { if ( threadid = tickid ) printf( "The tick thread has died naturally." ); }
I was actually wondering why there didn't seem to be a threading plugin yet, based on the source, the parameter known as 'pubname' defines a function to be executed by the thread. Also, I'm guessing the function loops until the thread is destroyed? If so, you should change that so that threads can die naturally without being told to, it is much easier to implement a loop than to perform logic to assume when would be a good time to call DestroyThread. That way you could also implement a OnThreadDeath callback.
That way something like this would work. Код:
new bool:active; new tickid; public OnGameModeInit() { tickid = ThreadCreate( "MyFunction" ); } public OnGameModeExit() { active = false; } public MyFunction() { active = true; while ( active ) { printf( "tick..." ); SleepThread( 1000 ); } } public onThreadDeath( threadid ) { if ( threadid = tickid ) printf( "The tick thread has died naturally." ); } |
This is variant not good. Very hard for pawn scripters and DestroyThread and not actual onThreadDeath( threadid ).
|
Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior. Many uses of stop should be replaced by code that simply modifies some variable to indicate that the target thread should stop running. |
I suppose people could just call DestroyThread at the end of the function, but it seems dangerous outside of that, what happens if you try to destroy a thread while its halfway through the function?
I recommend having a look at this, while its Java, it does give some insight as to the dangers of stopping a thread. |
new tickid; public OnGameModeInit() { tickid = CreateThread( "MyFunction" ); } public OnGameModeExit() { DestroyThread( tickid ); } public MyFunction( threadid ) { printf( "tick(%d)...", threadid ); SleepThread( 1000 ); }
public TimFunc2()
{
#if defined _use_threading
thTruckerCheck = CreateThread("TruckerCheck");
#else
SetTimer("TruckerCheck", 1000, 1);
#endif
return 1;
}
// in onplayerconnect
stock AdaugaPThread(playerid)
{
new lock2 = LockThread(thTruckerCheck);
Itter_Add(Player, playerid);
UnLockThread(lock2);
}
// in onplayerdisconnect
stock StergePThread(playerid)
{
new lock2 = LockThread(thTruckerCheck);
Itter_Remove(Player, playerid);
UnLockThread(lock2);
}
#endif
#if defined _use_threading
function TruckerCheck(threadid)
{
static dTruckerCheck;
if (!dTruckerCheck)
{
dTruckerCheck = true;
SleepThread(5000);
} else SleepThread(1020);
new lock = LockThread(threadid);
#else
function TruckerCheck()
{
#endif
static s_tmpST;
s_tmpST = GetTickCount();
foreach(Player, playerid)
{
if(gSofer[playerid])
{
if(PlayerIsStreamed(s_tmpST,playerid))
{
static s_stringTRK[128], Float:s_cHealth, tmpcar;
tmpcar = GetPlayerVehicleID(playerid);
if(tmpcar)
{
GetVehicleHealth(tmpcar, s_cHealth);
VehHealthBar(playerid,s_cHealth);
if(CarInfo[tmpcar][cModel] == 456 || CarInfo[tmpcar][cModel] == 440)
{
for(new i=0; i<=NumarBizuri; i++)
{
if(IsPlayerInRangeOfPoint(playerid, 10.0, BizzInfo[i][bEntranceX], BizzInfo[i][bEntranceY], BizzInfo[i][bEntranceZ]))
{
format(s_stringTRK, sizeof(s_stringTRK), "~w~%s~n~~r~Products Required~w~: %d~n~~y~Price per Product: ~w~: $%d~n~~g~Funds: ~w~: $%d",BizzInfo[i][bMessage],(BizzInfo[i][bMaxProducts]-BizzInfo[i][bProducts]),BizzInfo[i][bPriceProd],BizzInfo[i][bTill]);
GameTextForPlayer(playerid, s_stringTRK, 5000, 3);
}
}
}
}
}
}
}
#if defined _use_threading
UnLockThread(lock);
#endif
return 1;
}
Thread 10 (Thread 0xb23fbb90 (LWP 14012)): #0 0xb7fe37f2 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2 No symbol table info available. #1 0xb7fc6ef2 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib/libpthread.so.0 No symbol table info available. #2 0xb63965f5 in boost::condition_variable::timed_wait (this=0xb4c4ddc8, m=..., wait_until=...) at ../../../boost/thread/pthread/condition_variable.hpp:64 guard = {m = 0xb23fb224} check_for_interruption = {thread_info = 0xb4c4dd38, m = 0xb4c4ddc8, set = true} timeout = {tv_sec = 1309003835, tv_nsec = 153699000} cond_res = -1237759302 __PRETTY_FUNCTION__ = "bool boost::condition_variable::timed_wait(boost::unique_lock<boost::mutex>&, const boost::system_time&)" #3 0xb638fb0c in boost::this_thread::sleep (st=...) at ../src/pthread/thread.cpp:327 lk = {m = 0xb4c4ddb0, is_locked = false} thread_info = 0xb4c4dd38 #4 0xb6389e46 in Natives::n_SleepThread(tagAMX*, int*) () from plugins/Thread.so #25 0xb6394afc in boost::pthread::pthread_mutex_scoped_lock::pthread_mutex_scoped_lock(._12 *) (this=0x8934cd8, m_=0xa5) at ../../../boost/thread/pthread/pthread_mutex_scoped_lock.hpp:26 No locals. Backtrace stopped: previous frame inner to this frame (corrupt stack?)
Thread 3 (Thread 0xb6ebfb90 (LWP 13960)): #0 0xb7fe37f2 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2 No symbol table info available. #1 0xb7dd7d26 in nanosleep () from /lib/libc.so.6 No symbol table info available. #2 0xb7e1188c in usleep () from /lib/libc.so.6 No symbol table info available. #3 0xb7bfd4b7 in ProcessQueryThread (lpParam=0x0) at main.cpp:189
There is a reason there is no threading plugins already, especially not ones which actually run PAWN functions in a mode! PAWN is not designed to be multi-threaded and there are no guarantees AT ALL on your data the moment you introduce threads.
You might want to make it VERY clear in the first post that using this can significantly corrupt your gamemode before people who don't know what they're doing try and use it... |