Get own threadID without passing as parameter

Just starting out? Need help? Post your questions and find answers here.
LiK137
Enthusiast
Enthusiast
Posts: 282
Joined: Wed Jun 23, 2010 5:13 pm

Re: Get own threadID without passing as parameter

Post by LiK137 »

Dear BarryG,
The global variable assignment is not suitable for my post as these threads being created by networkSever procedure which may have to create more threads than global declarations.

Thank You very much.
User avatar
Olliv
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Sep 22, 2009 10:41 pm

Re: Get own threadID without passing as parameter

Post by Olliv »

@Lik137

First...

Code: Select all

Procedure Zot(void.Q)
   Define uit.Q
   ! mov [p.v_uit + 72], rax ; threadId 
   Debug uit
   Delay(2000)
EndProcedure

Debug ThreadId(createthread(@Zot(), 0) )
Delay(5000)
End
You see it is the same value inside and outside. But normally, a protecting error will be done in the future CPU. (hardware, not software)

Purebasic is a software.
User avatar
Olliv
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Sep 22, 2009 10:41 pm

Re: Get own threadID without passing as parameter

Post by Olliv »

Secondly... I do not waste my time : all is already explained above, and the source code date is 2009.

If you have technical questions about it, no problem : I will just cut extract after extract a source code part to explain it.

And it is very very easy to include the recent network process I published. Etc... Etc...

Peace my friend !!
:mrgreen:
User avatar
Olliv
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Sep 22, 2009 10:41 pm

Re: Get own threadID without passing as parameter

Post by Olliv »

infratec wrote:Extended version without global variables:

Code: Select all

Structure ThreadParameterStructure
  Thread.i
  Delay.i
EndStructure

Procedure test(*ThreadParameter.ThreadParameterStructure)
  Debug "CurrentProcessId: " + GetCurrentProcessId_()
  Debug "CurrentThreadId : " + GetCurrentThreadId_()
  ;Debug "CurrentThread   : " + GetCurrentThread_()
  
  Delay(*ThreadParameter\Delay)
  
EndProcedure

Define ThreadParameter.ThreadParameterStructure

ThreadParameter\Delay = 20000
ThreadParameter\Thread = CreateThread(@test(), @ThreadParameter)

Debug "Outside Thread: " + ThreadParameter\Thread
Debug "Outside ThreadID: " + ThreadID(ThreadParameter\Thread)

Delay(25000)
Since you need (normally) always parameters, you can add them in the structure.
This code part is right.

I have two remarks about these recent questions.

1) I recommand dynamic pointors, even in basis (out of procedures)

Code: Select all

Structure Root

   Head.I

   Map aMap.Key()
   Array anArray.Field(0)

EndStructure

Define *R.Root = AllocateStructure(Root)
CreateThread(@ObjectCreate(), *R)
; etc...
This allows a "perfect" (near one integer) memory managing of maps and arrays.
This allows any backup, swap, levelling or thread buffer root.


2) I think about such any questions about links between thread clients and process.

Now, I realize : if anybody began his coding by single procedures with specific arguments, without bus neither common argument, so there is a real converting problem to thread these procedures if a ThreadId() function is missing.

In this way (but it was not explicit in the question), Threaded could be used to prevent from variable name conflict, Global.ThreadStructure *P to share all information between every thread. (There is just a problem of data security)
LiK137
Enthusiast
Enthusiast
Posts: 282
Joined: Wed Jun 23, 2010 5:13 pm

Re: Get own threadID without passing as parameter

Post by LiK137 »

Dear Olliv,
Thank You for your reply.
Unfortunately neither this for pb5.71x64 Win7:

Code: Select all

Procedure Zot(void.Q)
   Define uit.Q
   ! mov [p.v_uit + 72], rax ; threadId
   Debug uit
   Delay(2000)
EndProcedure

Debug ThreadID(CreateThread(@Zot(), 0) )
Delay(5000)
End
nor this for pb5.71x86 Win7:

Code: Select all

Procedure Zot(void)
   Define uit
   ! mov [p.v_uit + 72], eax ; threadId
   Debug uit
EndProcedure

Define thdID = CreateThread(@Zot(), 0)
Debug ThreadID(thdID)
Delay(5000)
End
give anything close to pb ThreadID.
User avatar
Shardik
Addict
Addict
Posts: 2060
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Get own threadID without passing as parameter

Post by Shardik »

The documentation of ThreadID() states that the result of ThreadID() returns a handle:
[color=#0040FF][u]Documentation for ThreadID()[/u][/color] wrote:Return value

The system identifier. This result is sometimes also known as 'Handle'. Look at the extra chapter Handles and Numbers for more information.
Indeed the return parameter of ThreadID() is not the ID but the thread handle. You therefore have to convert the thread handle to a thread ID as DarkPlayer has already demonstrated. After inserting his procedure GetThreadIDFromHandle() into LiK137's previous code example, the outside ThreadID will be the same as the inside ThreadID... :wink:

Code: Select all

#ThreadBasicInformation = 0

Structure CLIENT_ID
   UniqueProcess.i
   UniqueThread.i
EndStructure

Structure THREAD_BASIC_INFORMATION
  ExitStatus.l
  TebBaseAddress.i
  ClientId.CLIENT_ID
  AffinityMask.l
  Priority.l
  BasePriority.l
EndStructure

Procedure Test(Dummy.i)
  Debug "Inside ProcessID: " + GetCurrentProcessId_()
  Debug "Inside ThreadID: " + GetCurrentThreadId_()
  Delay(10)
EndProcedure

Procedure GetThreadIDFromHandle(Handle.i)

  Protected Info.THREAD_BASIC_INFORMATION

  If NtQueryInformationThread_(Handle, #ThreadBasicInformation, @Info,
    SizeOf(Info), 0) = 0
    ProcedureReturn Info\ClientId\UniqueThread
  EndIf

EndProcedure

Define Thread.i = CreateThread(@Test(), 0)

Debug "Outside ThreadID: " + GetThreadIDFromHandle(ThreadID(Thread))

Delay(10000)
infratec
Always Here
Always Here
Posts: 7617
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Get own threadID without passing as parameter

Post by infratec »

Hre you can find the short interpretation of PBs ThreadID()

https://www.purebasic.fr/english/viewto ... 94#p553494

Unfortunately you get only a virtual thread handle inside the thread.
infratec
Always Here
Always Here
Posts: 7617
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Get own threadID without passing as parameter

Post by infratec »

If yuo really need the thread handle inside the thread,
you can only use DuplicateHandle() to create a handle which uses the same handle.
But you have to close it with CloseHandle().

Or maybe OpenThread()

Code: Select all

Import ""
  GetThreadId.l(Handle.i)
  OpenThread.l(dwDesiredAccess.l, bInheritHandle.l, dwThreadId.l)
  CloseHandle.l(hObject.l)
EndImport


Procedure test(dummy.i)
  Debug "CurrentProcessId      : " + GetCurrentProcessId_()
  Debug "CurrentThreadId       : " + GetCurrentThreadId_()
  Debug "Virtual CurrentThread : " + GetCurrentThread_()
  
  Debug "CurrentThreadId by OS via virtual CurrentThread : " + GetThreadID(GetCurrentThread_())
  
  Handle.i = openthread($00020000, #False, GetCurrentThreadId_())
  Debug Handle
  If Handle
    closehandle(Handle)
  EndIf
  
  Delay(20000)
  
EndProcedure


Define Thread.i = CreateThread(@test(), 0)

Debug "Outside Thread: " + Thread
Debug "Outside ThreadID PB (not the ThreadID, only a HANDLE) : " + ThreadID(Thread)
Debug "Outside ThreadID OS: " + GetThreadID(ThreadID(Thread))

Delay(25000)
LiK137
Enthusiast
Enthusiast
Posts: 282
Joined: Wed Jun 23, 2010 5:13 pm

Re: Get own threadID without passing as parameter

Post by LiK137 »

Shardik,
Thanks for information.
the procedure returning ThreadHandle called ThreadID()
That is my fault to create a post with wrong identification.

In fact I need the handle of the own thread (from inside of ThreadProcedure) to be able the handle to be used in PB Thread procedures.

Thanks very much
infratec
Always Here
Always Here
Posts: 7617
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Get own threadID without passing as parameter

Post by infratec »

You should be able to use the handle from OpenThread()
LiK137
Enthusiast
Enthusiast
Posts: 282
Joined: Wed Jun 23, 2010 5:13 pm

Re: Get own threadID without passing as parameter

Post by LiK137 »

infratec,
many thanks to you for the solution.
These solutions from You, shardik, NicTheQuick (for Linux) really will be useful for me and solve my problem mentioned.
We now are able to get real ThredID form ThreadHandle. I will be once more very thankful for reverse, getting ThreadHandle (same Handle obtained by ThreadID()) from ThreadID (obtained from GetCurrentThreadId_()).
User avatar
Shardik
Addict
Addict
Posts: 2060
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Get own threadID without passing as parameter

Post by Shardik »

LiK137 wrote:I will be once more very thankful for reverse, getting ThreadHandle (same Handle obtained by ThreadID()) from ThreadID (obtained from GetCurrentThreadId_()).
I have expanded my last example to also display the thread handle obtained from the ThreadID (and replaced the procedure GetThreadIDFromHandle() by the much shorter GetThreadID() as proposed by infratec):

Code: Select all

Import ""
  GetThreadId(ThreadHandle.I)
  OpenThread(dwDesiredAccess.L, bInheritHandle.I, dwThreadId.L)
EndImport

Procedure Test(Dummy.I)
  Protected ThreadHandle.I

  Debug "Inside ProcessID: " + GetCurrentProcessId_()
  Debug "Inside ThreadID: " + GetCurrentThreadId_()
  ThreadHandle = OpenThread(#THREAD_ALL_ACCESS, 0, GetCurrentThreadId_())

  If ThreadHandle
    Debug "Inside ThreadHandle: " + ThreadHandle
    CloseHandle_(ThreadHandle)
  EndIf

  Delay(10)
EndProcedure

Define Thread.I = CreateThread(@Test(), 0)

Debug "Outside ThreadID: " + GetThreadID(ThreadID(Thread))

Delay(10000)
LiK137
Enthusiast
Enthusiast
Posts: 282
Joined: Wed Jun 23, 2010 5:13 pm

Re: Get own threadID without passing as parameter

Post by LiK137 »

Shardic,
just added one line:
Debug "Outside ThreadHandle: " + ThreadID(Thread)
and increased threads
to compare inner and outer values

Code: Select all

Import ""
  GetThreadId(ThreadHandle.I)
  OpenThread(dwDesiredAccess.L, bInheritHandle.I, dwThreadId.L)
EndImport

Procedure Test(Dummy.I)
  Protected ThreadHandle.I

  Debug "Inside ProcessID: " + GetCurrentProcessId_()
  Debug "Inside ThreadID: " + GetCurrentThreadId_()
  ThreadHandle = OpenThread(#THREAD_ALL_ACCESS, 0, GetCurrentThreadId_())

  If ThreadHandle
    Debug "Inside ThreadHandle: " + ThreadHandle
    Debug "_____________________________________________"
    CloseHandle_(ThreadHandle)
  EndIf

  Delay(10)
EndProcedure

Define Thread1.I = CreateThread(@Test(), 0)
Define Thread2.I = CreateThread(@Test(), 10)
Define Thread3.I = CreateThread(@Test(), 100)

Debug "Outside ThreadHandle1: " + ThreadID(Thread1)
Debug "Outside ThreadID1: " + GetThreadID(ThreadID(Thread1))
Debug "------------------------------------------------------"

Debug "Outside ThreadHandle2: " + ThreadID(Thread2)
Debug "Outside ThreadID2: " + GetThreadID(ThreadID(Thread2))
Debug "------------------------------------------------------"

Debug "Outside ThreadHandle3: " + ThreadID(Thread3)
Debug "Outside ThreadID3: " + GetThreadID(ThreadID(Thread3))
Debug "------------------------------------------------------"

Delay(10000)
still inner differs from outer threadHandle

DebugOutput:
[17:56:43] Inside ProcessID: 10532
[17:56:43] Inside ThreadID: 5956
[17:56:43] Inside ThreadHandle: 196
[17:56:43] _____________________________________________
[17:56:43] Inside ProcessID: 10532
[17:56:43] Inside ThreadID: 8312
[17:56:43] Inside ThreadHandle: 208
[17:56:43] _____________________________________________
[17:56:43] Outside ThreadHandle1: 180
[17:56:43] Outside ThreadID1: 5956
[17:56:43] ------------------------------------------------------
[17:56:43] Outside ThreadHandle2: 184
[17:56:43] Outside ThreadID2: 8312
[17:56:43] ------------------------------------------------------
[17:56:43] Outside ThreadHandle3: 196
[17:56:43] Outside ThreadID3: 13048
[17:56:43] ------------------------------------------------------
[17:56:43] Inside ProcessID: 10532
[17:56:43] Inside ThreadID: 13048
[17:56:43] Inside ThreadHandle: 216
[17:56:43] _____________________________________________
infratec
Always Here
Always Here
Posts: 7617
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Get own threadID without passing as parameter

Post by infratec »

Of course it differs.

OpenThread() returns a new handle, but it opens the 'original' thread.

If you want the original thread, you get only a 'pseudo' thread, which you can not use with PB (I think).
LiK137
Enthusiast
Enthusiast
Posts: 282
Joined: Wed Jun 23, 2010 5:13 pm

Re: Get own threadID without passing as parameter

Post by LiK137 »

Hmm, then can this be considered as no way to get PB assigned ThreadHandle from inside?
Post Reply