The current thread id

Windows specific forum
Damion12
User
User
Posts: 81
Joined: Tue Oct 30, 2012 1:39 am

The current thread id

Post by Damion12 »

I am updating program someone else wrote. They use threadid wrongly.
is there way to get "current thread" id from purebasic? (the value of ThreadID(), but by not knowing thread handle) Like windows api GetCurrentThreadId() but for purebasic handle.

In order to pass it on createthread() would require lots of change to other functions that are generic and not needing thread info.
User avatar
Keya
Addict
Addict
Posts: 1891
Joined: Thu Jun 04, 2015 7:10 am

Re: The current thread id

Post by Keya »

you can use GetWindowsThreadId like you said to get the Windows handle of the thread (and i think Purebasic's ThreadID() function is a wrapper for that on Windows), but for the Purebasic internal thread id you get that as a result of a successful call to PB's CreateThread() function:

Code: Select all

  ThreadId = CreateThread(@ProcedureName(), *Value)
but in re-reading your question it seems you're after the id of the main/existing thread, hmmm... i'm not sure about that one, good question! I tried a few things but was unsuccessful
Damion12
User
User
Posts: 81
Joined: Tue Oct 30, 2012 1:39 am

Re: The current thread id

Post by Damion12 »

Keya wrote:you can use GetWindowsThreadId like you said to get the Windows handle of the thread (and i think Purebasic's ThreadID() function is a wrapper for that on Windows)
GetWindowsThreadId() does not return the same value as ThreadID().
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4659
Joined: Sun Apr 12, 2009 6:27 am

Re: The current thread id

Post by RASHAD »

Hi
PB x32,PB x64 - Windows 10 x64

Code: Select all

Prototype GetThreadId(hTnd.i)
Global GetThreadId.GetThreadId

Structure CLIENT_ID
   UniqueProcess.i
   UniqueThread.i
EndStructure

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

Procedure GetThreadIDFromHandle(Handle.i)

  Protected Info.THREAD_BASIC_INFORMATION

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

EndProcedure


Procedure GetThread_ID(para)
  Repeat
    Delay(10)
    x + 1
  Until x > 50000
EndProcedure

HThread = CreateThread(@GetThread_ID(),30)

Debug GetThreadIDFromHandle(ThreadID(HThread))

If OpenLibrary(0, "kernel32.dll")
    GetThreadId = GetFunction(0, "GetThreadId")
    Debug GetThreadId(ThreadID(HThread))
    CloseLibrary(0)
EndIf
Edit :Modified for PB x64
Egypt my love
Damion12
User
User
Posts: 81
Joined: Tue Oct 30, 2012 1:39 am

Re: The current thread id

Post by Damion12 »

VERY Nice RASHAD! but I need other way. Given GetCurrentThreadId_() what is Purebasic ThreadID?
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4659
Joined: Sun Apr 12, 2009 6:27 am

Re: The current thread id

Post by RASHAD »

I not sure I got you correctly

Code: Select all

Prototype GetThreadId(hTnd.i)
Global GetThreadId.GetThreadId

Procedure GetThread_ID(para)
  Repeat
    Delay(10)
    x + 1
  Until x > 50000
EndProcedure

CreateThread(@GetThread_ID(),30)

If OpenLibrary(0, "kernel32.dll")
    GetThreadId = GetFunction(0, "GetThreadId")
    For t = 1 To 10
      If GetThreadId(ThreadID(t)) > 0
         If IsThread(t)
           Break
         EndIf
      EndIf
    Next
    Debug "PB_Thread_ID : "+Str(t)
    CloseLibrary(0)
EndIf
Egypt my love
Damion12
User
User
Posts: 81
Joined: Tue Oct 30, 2012 1:39 am

Re: The current thread id

Post by Damion12 »

RASHAD: sorry. maybe this explain better?

Code: Select all


; This is in a dll 
Procedure SomeFunctionInDLL()
	; What is my thread id?
	Debug GetCurrentThreadId_() ; Nope, how to tell what the id of this running thread?
	; how to find purebasic's "thread id" as displayed in main ?
	Repeat
    Delay(10)
  ForEver
EndProcedure
  
; this is locked in an exe 
Procedure ProgramProcedureThread(n)
	; Call function, pretend is in dll
	SomeFunctionInDLL() ; pretend this function in dll.
EndProcedure

; main program
t = CreateThread(@ProgramProcedureThread(),0)
Debug ThreadID(t) ; I need to know this # w/o having it passed to the thread or a global var

Delay(100)
I can modify the dll, but previous program assumed GetThreadID_() is same as purebasic threadid() and never tested. so "program" is static, only dll procedure I can change
jassing
Addict
Addict
Posts: 1764
Joined: Wed Feb 17, 2010 12:00 am

Re: The current thread id

Post by jassing »

What I'm trying to do is do some prep work (attach thread), then cleanup work on exit.
Attempting to send data back to the application in a threadsafe way w/o gobbling up memory.

Looks like GetCurrentThreadId_() will work as an identifier, but cannot use attachthread to do any prep work, as it does not always get called with an associated detach call.

But curious, that as the DLL is loaded, there are 3 calls to AttachThread that do not have an associated DetachThread call.

Code: Select all

[5672] AP 3668
[5672] AT 1356
[5672] AT 7752
[5672] AT 7480
[5672] -- In program --------------

...

[5672] -- End Program-----------
[5672] DP 3668
[/code]
As well as a couple of spurious AttachThread() calls made in the middle of processing.
(Yellow highlighted items never have a detach call...)
Image

FWIW, here's the code I used.

Code: Select all

; SomeFunc.pb

CompilerIf #PB_Compiler_ExecutableFormat = #PB_Compiler_DLL
  ProcedureDLL SomeFunctionInDLL(b)
    Protected t
    If b
    t = CreateThread(@SomeFunctionInDLL(),#False)
    EndIf 
    OutputDebugString_("SF("+Str(b)+") "+Str(GetCurrentThreadId_()))
    Repeat : Delay(5) : Until IsThread(t) = #False 
  EndProcedure  

  ProcedureDLL AttachProcess(n)
    OutputDebugString_("AP "+Str(GetCurrentThreadId_())) 
  EndProcedure
  ProcedureDLL DetachProcess(n)
    OutputDebugString_("DP "+Str(GetCurrentThreadId_())) 
  EndProcedure
  ProcedureDLL AttachThread(n)
    OutputDebugString_("AT "+Str(GetCurrentThreadId_())) 
  EndProcedure
  ProcedureDLL DetachThread(n)
    OutputDebugString_("DT "+Str(GetCurrentThreadId_())) 
  EndProcedure
 
CompilerElse
  Import "SomeFunc.lib"
    SomeFunctionInDLL(b)
  EndImport
  
  Procedure ProgramProcedureThread(tc)
    If tc = 1 : tmp.s = "--First": Else : tmp.s = "--Second" : EndIf
    OutputDebugString_(tmp+" Thread, 1st call ---------")
    SomeFunctionInDLL(#True) 
    If tc = 1 : Delay(400) : Else : Delay(600) : EndIf 
    OutputDebugString_(tmp+"-- Thread, 2nd call -------")
    SomeFunctionInDLL(#True) 
    OutputDebugString_(tmp+"-- Thread, Done -----------")
  EndProcedure
  
  OutputDebugString_("-- In program --------------")
  
  OutputDebugString_("threadID "+Str(GetCurrentThreadId_()))
  ; main program
  t1 = CreateThread(@ProgramProcedureThread(),1)
  Delay(50)
  t2 = CreateThread(@ProgramProcedureThread(),2)
  Repeat 
    Delay(100)
  Until IsThread(t1)=#False And IsThread(t2)=#False 
OutputDebugString_("-- End Program-----------")
CompilerEndIf
  
; IDE Options = PureBasic 6.01 LTS (Windows - x64)
; ExecutableFormat = Shared dll
; CursorPosition = 2
; Folding = ---
; Optimizer
; EnableThread
; EnableXP
; Executable = SomeFunc.dll
; EnablePurifier
; EnableCompileCount = 36
; EnableBuildCount = 13
; EnableExeConstant
Post Reply