Author Topic: Threads  (Read 3349 times)

0 Members and 1 Guest are viewing this topic.

Charles Pegge

  • Guest
Threads
« on: May 08, 2011, 07:01:31 AM »
Sooner or later we are going to need them.
I will include this in examples\system\threads

I'm thinking about running Windows asynchronously using Oxygen embedded in ScriptBasic...

Code: [Select]

  '----------------
  'MULTIPLE THREADS
  '================



  #define NULL     0
  #define FALSE    0
  #define TRUE     1
  #define IGNORE   0           'Ignore signal
  #define INFINITE 0xFFFFFFFF  'Infinite timeout

  #define __in
  #define __out
  #define __in_opt
  #define __out_opt
  #define __in_ecount(nCount)

  #define MAX_THREADS 3

  'Sample custom data structure for threads to use.
  'This is passed by void pointer so it can be any data type
  'that can be passed using a single void pointer (LPVOID).
  '
  type dtype sys val1,val2

  typedef sys   HANDLE,SIZE_T
  typedef void  *LPVOID, *LPSECURITY_ATTRIBUTES, *LPTHREAD_START_ROUTINE
  typedef dword *LPDWORD

  '================================
  extern stdcall lib "kernel32.dll"
  '================================


  HANDLE CreateThread
  (
    __in_opt  LPSECURITY_ATTRIBUTES lpThreadAttributes,
    __in      SIZE_T dwStackSize,
    __in      LPTHREAD_START_ROUTINE lpStartAddress,
    __in_opt  LPVOID lpParameter,
    __in      DWORD dwCreationFlags,
    __out_opt LPDWORD lpThreadId
  )


  DWORD WaitForMultipleObjects
  (
    __in DWORD nCount,
    __in_ecount(nCount) CONST HANDLE *lpHandles,
    __in BOOL bWaitAll,
    __in DWORD dwMilliseconds
  )



  BOOL CloseHandle
  (
    __in HANDLE hObject
  )


  end extern

  sys counter

  '-------------------------------------------
  function ThreadA( dtype*pd ) as sys external
  '===========================================
  finit
  inc counter
  print "Thread A: " pd.val1 "    " pd.val2 "    " + counter
  return 0
  end function

  '-------------------------------------------
  function ThreadB( dtype*pd ) as sys external
  '===========================================
  finit
  inc counter
  print "Thread B: " pd.val1 "    " pd.val2 "    " + counter
  return 0
  end function

  '-------------------------------------------
  function ThreadC( dtype*pd ) as sys external
  '===========================================
  finit
  inc counter
  print "Thread C: " pd.val1 "    " pd.val2 "    " + counter
  return 0
  end function


  #define MAX_THREADS 3

  LPTHREAD_START_ROUTINE FunArray[MAX_THREADS]<=(&ThreadA,&ThreadB,&ThreadC)


  '--------------
  function main()
  '==============

  dtype  tdata[MAX_THREADS]
  dword  dwThreadIdArray[MAX_THREADS]
  HANDLE hThreadArray[MAX_THREADS]
  sys    i

  'Create MAX_THREADS worker threads.
  '----------------------------------

  for i=1 to MAX_THREADS
    '
    'Generate some unique data for each thread to work with.
    '------------------------------------------------------
    '  
    tdata[i].val1=i : tdata[i].val2=i+100
    '
    'Create the thread to begin execution on its own.
    '------------------------------------------------
    '
    hThreadArray[i] = CreateThread
    (
    byval NULL,              'default security attributes
    0,                       'use default stack size  
    byval FunArray[i],       'thread function
    tdata[i],                'argument to thread function
    0,                       'use default creation flags
    dwThreadIdArray[i]       'returns the thread identifier
    )
    '
    'print "ThreadID: " dwThreadIdArray[i]
    '
    'Check the return value for success.
    'If CreateThread fails, terminate execution.
    'This will automatically clean up threads and memory.
    '
  next 'End of main thread creation loop.
  '
  'print "All threads up and running"
  '
  'Wait until all threads have terminated.
  '---------------------------------------
  '
  WaitForMultipleObjects(MAX_THREADS, hThreadArray, TRUE, INFINITE)
  '
  'Close all thread handles and free memory allocations.
  '-----------------------------------------------------
  '
  for i=1 to MAX_THREADS
    CloseHandle( hThreadArray[i] )
  next
  '
  return 0
  '
  end function 'main

  main()

  print "All thread are closed. Program will now terminate"



Charles
« Last Edit: May 08, 2011, 07:04:45 AM by Charles Pegge »

JRS

  • Guest
Re: Threads
« Reply #1 on: May 08, 2011, 10:44:35 AM »
Quote
I'm thinking about running Windows asynchronously using Oxygen embedded in ScriptBasic...

If you want to see an example of ScriptBasic being used in a multi-threaded environment, have a peek at sbhttpd. This web server variation supplied with the distribution shows SB creating threads (within the same process) to handle CGI requests, sharing variables between threads (MT extension module) and running as a service. I think SB provides everything you need as a framework to run O2h asynchronously in a threaded environment.

Check out the developers guide at www.scriptbasic.org/wiki

Charles Pegge

  • Guest
Re: Threads
« Reply #2 on: May 08, 2011, 12:23:54 PM »
Hi John,

The idea I had in mind was to facilitate a Windows GUI for  ScriptBasic programs. To support the exchange of data between SB and GUI at least one thread has to operate on the Oxygen side.

The entire Windows GUI runs freely inside this thread. while the non-thread part of SBO2 services data exchange between the GUI and the SB application.

Charles

JRS

  • Guest
Re: Threads
« Reply #3 on: May 08, 2011, 02:36:36 PM »
Sounds like a great plan! One of the major issues with getting Basic programmers to use SB for Windows is a lack of native GUI and graphics. (OpenGL) O2h as a JIT compiler is a huge bonus. Where can I find more info on the OXYGEN.DLL API? The help file seems to skip over this or maybe I'm not looking in the right place.

I would like to embed a O2h script in a SB script that would generate a DLL that I can call at runtime. (using DYC as the FFI)

Can't wait till you have a Linux version of O2h to work with.
« Last Edit: May 08, 2011, 07:41:31 PM by JRS »

Charles Pegge

  • Guest
Re: Threads
« Reply #4 on: May 08, 2011, 08:58:14 PM »
John,

There is a manual detailing the Oxygen DLL calls included with thinBasic. I need to transfer the relevant sections. You will also find FB source code for the compilers gxo2 and exo2 in the /tools section. They will show how Oxygen is used to compile and/or provide listings and report errors.

What we don't have yet is communications between ScriptBasic and an Oxygen compiled program that is actively running.

Charles

Charles Pegge

  • Guest
Re: Threads
« Reply #5 on: May 09, 2011, 11:31:54 AM »

I've posted an example demonstrating how to run a full Windows GUI inside a thread.

This is the key function which is attached to the thread. As you can see, it
performs the setup and invokes WinMain. Thread functions can only take 1 parameter and this is usually a pointer to a block of static data. So it is not possible to thread WinMain directly.

Code: [Select]
  '----------------------------------------------
  function window(sys*SharedData) as sys external
  '==============================================
  '
  finit 'FPU gets messed up and needs reinitialising!
  zstring* cmdline
  &cmdline=GetCommandLine
  sys instance=GetModuleHandle 0
  '
  WinMain instance,0,cmdline,SW_NORMAL
  '
  end function

It is available in the Oxygen in-progress download. examples/system/threads

Charles