News:

One Minute Game Review by The Happy Friar: https://ugetube.com/@OneMinteGameReviews
Also on Rumble: https://rumble.com/c/c-1115371

idTech 4 (aka Doom 3 tech) Discord Server! https://discord.gg/9wtCGHa

Main Menu

identify threads

Started by BielBdeLuna, June 10, 2015, 01:04:07 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

BielBdeLuna

you can name a thread with a string name (what is the point?)

but can you save the thredId number?

you can kill a thread, but for that you need the threadId number, a float

is there a way to get the threadId number so I can kill that thread at will?

motorsep

It's not possible out of the box.

What is the practical application for killing a thread? I don't think I saw anything for that case in Doom 3 so I naturally wonder about it.

BielBdeLuna

#2
the idea of not wasting cycles with it if it is uneeded, you could stop a process and reignite it when needed. it's a capacity to stop a while or a for loop out of the loop (without a break)

wow! nevermind a long time ago I read it wrong because killthread does use a string variable so now naming the thread makes totally sense! man I feel stupid now! :-[ ;D

motorsep

so for example if you have a function that sets up your map and need to be executed only once, will be executing forever? Or is it only critical for while(1) loops ?

BielBdeLuna

in the case of a while(1) or while (true) loops, yes, until d3 kills the thread by killing the entity that created it, on exiting the map, or when killing the monster itself,  and if the loop is initiated in the map script, exiting the map will kill the loop, but the question is amidst gameplay, if you have too many loops running you could choke the cpu, in the case of the standard monster from the c++ there are five loops created per monster: 1 loop per entity, that initiates init() and destroys with destroy() (which is applicable to all entities), an then one loop for states,  another for animating the legs, another for animating the head and another for animating the torso.

if you add the loops for the player, the loops for the current weapon

there is a lot of loops going on within normal gameplay, if you keep adding loops, and specially if those loops use the "waitForFrame()" (so they are 60fps loops in BFG at least) you get the picture.

if you make your loops with time deltas of 0.1 (10 fps), 0.04 (25fps) or 0.0333 ( roughly 30fps ) you might get away with more loops.

the loops started in c++ use the same class "idThread" as the ones within the script system. so I guess those are the same initiated at different stages.

The Happy Friar

From the doom 3 scripting help file:

Quotevoid killthread( string threadName ) // Kills all threads with the specified name
so thread names are so you can kill them.


There's also "listThreads" but that is a console command, not a script command.



I want to say Bloodrayne did a good amount with threads in his mod.  Hopefully he will chime in.


BielBdeLuna

yeah, some time ago I misread the modwiki with the threads, and i get the impression that kilthread needed a float variable, which weren't true, hence my troubles and misunderstandings. in c++ the thread are usually refereed to a int number, so I automatically expected to be the same in idtech script, this and me misreading the definition got me into trouble  :-[ sorry to bother with my crap  ;D

The Happy Friar

No, not a bad question because you can terminate a thread via the id.  I just don't know how to find that.

motorsep

True, can be either name or ID:


static void KillThread( const char* name );
static void KillThread( int num );

BielBdeLuna

#9
ok.

maybe something like this would work?

void superCoolThread() { while( true ) { sys.print( "super cool all the way!" ); } };

void execute() {

    float threadIdNum = thread superCoolThread();

    sys.wait( 3 );

    sys.killthread( threadIdNum );
}


so float threadIdNum would get the actual thread idNumber as a return from the byproduct of creating it, I think that's how is done in c++


motorsep

I think it should look like this:


void superCoolThread() {
while( 1 ) {
sys.println( "super cool all the way!" );
sys.wait( 0.1 ); // if you don't have some wait inside the loop, you will get runaway loop error
}
}

void executeTermination() {
    sys.println( "Thread is terminated!" );
    sys.killthread( superCoolThread );
}


Then you'd call namespace::superCoolThread in the worldspawn and have a trigger that runs namespace::executeTermination script. So when you trip the trigger, your printing should stop.

BielBdeLuna

yes but I intended it to work somewhat different when you execute (of course inside a namespace for a testmap) you want to start the thread and then kill it n seconds latter.

but anyways the intention was to see if it returned a float num when created a new thread.

motorsep

Why don't you test it with trigger first, making sure you indeed can terminate a thread, and then figure out how to do it with time delay?

For time delay you'd need to get start time and then add delay to it, then keep getting current time until current time is => than delay time, and if that's the case, you will call executeTermination() function.

So you would have 4 functions: superCoolThread(), delayTimer(), executeTermination() and main().

main() will contain calls for superCoolThread() and delayTimer() and will be called in the worldspawn.

delayTimer() will call executeTermination() when it's time to terminate superCoolThread() thread.

BielBdeLuna

why do you explain to me how to get a delayed time? you didn't understood why was I making that code, isn't it? :-\

I don't need to test how to delay anything or how to kill threads I know how to do all this.

the point wasn't in any of this. The point was to register the threadId in a meaningful way

i've found that threads when created do generate and expose a float to the script code, but Kilthread doesn't seem to understand it, it just doesn't kill the thread, so in order to kill the thread I had to go the "threadname" route and use a string.

so this:

    void superCoolThread() { sys.threadname( "coolthread" ); while( true ) { sys.println( "super cool all the way!" ); sys.waitFrame(); } }

    void execute() { // called by the map
        float threadIdNum = 78;
        sys.println( threadIdNum );
        threadIdNum = thread superCoolThread();
        //thread superCoolThread();

        sys.wait(0.1);

        //sys.killthread( threadIdNum );
        sys.killthread( "coolthread" );
        sys.println( threadIdNum );
    }


ends up with this results in the console:

Quote78
super cool all the way!
super cool all the way!
super cool all the way!
super cool all the way!
super cool all the way!
super cool all the way!
super cool all the way!
10

so the number in the end is no longer 78 but 10, and if I keep doing it it then becomes 12 and then 14, so there is a consistency here

I bet is the following:

amount of threads already running +  a new thread every time I call "execute" from the map trigger + the thread I created within that script = number given which become the new amount of threads already running, that's the reason it increments with 2 from the last number given.

I guess this is the number assigned, it doesn't mean that killing the thread won't kill it, but the number keeps going up whether the thread keeps going or not.

so yes the threadId can be gathered.  :D


motorsep

#14
Quote from: BielBdeLuna on June 11, 2015, 01:38:08 PM
why do you explain to me how to get a delayed time?

Sorry, but maybe because you don't explain correctly what you are after and what you are doing?

:/

I still don't get why do you care for thread ID if you managed to kill it via name o.O