Forum > Beginners

Passing an array to a Threadfunction.

(1/1)

jddev:
Hi, folks.
I'm not newto Pascal programming, but to thread-programming.

I want to pass an Array filled with Byte-values to a threaded function, but al i tried doe'nt  work, yet.
Here is a minimal example of my current try:

{$mode obfpc}
program miniexp;

uses
  {$ifdef UNIX} cthreads; {$endif}
 
type
  TByteArray = Array of Byte;
  PByteArray = ^TByteArray;
  TArrIndex = Byte;

var
  AnArray : TByteArray; (* Array to pass *)
  ArrAddr : PByteArray; (* addres of AnArray *)
  lc :  TArrIndex; (* loopcounter *)
  thisd : TThreadid; (* threadid *)

(*this function just pronts the passed array.*)
function miniexp(pt : pointer) : ptrint;
var
  toPrint : TByteArray;
  idx : TArrIndex;
begin
  toPrint :=  PByteArray(pt);

  for idx := low(toPrint) to high(toPrint) do
  begin
     writeln(toPrint[idx]);
  end;

   miniexp := 0;
   EndThread;
end;
 
Begin
  SetLength(AnArray, 10); (*set array to proper length*)

  (* fill the array*)
  randomize;
   for lc := low(AnArray) to high(AnArray) do
   begin
      AnArray[lc] := (random(521) mod 256);
   end; 
 
   (*The following works, but does'nt pass the full array. *)
    ArrAddr := @AnArray;
    thid := BeginThread(TThreadfunc(@miniexp), pointer(ArrAddr));
    WaitForThreadTerminate(thid, 1000000);

End.
(*of miniexample.*)

Any suggestions arewelcome.

With greets and respect,
jddev.

marcov:
The best advise would probably to not use automated types for pointer tricks.  Probably the main thread deallocates the memory behind your back because it is no longer used. Allocate your memory buffer with getmem.

A standard trick is also to put the automated type inside a record or class, and pass the pointer to the record or class to the thread.

I would also advise you to use tthread.

Blaazen:
Your code compiles here (FPC 2.7.1), with only a small change:

--- Code: ---program miniexp;
{$mode objfpc}

uses
  {$ifdef UNIX} cthreads; {$endif}
 
type
  TByteArray = Array of Byte;
  PByteArray = ^TByteArray;
  TArrIndex = Byte;

var
  AnArray : TByteArray; (* Array to pass *)
  ArrAddr : PByteArray; (* addres of AnArray *)
  lc :  TArrIndex; (* loopcounter *)
  thid : TThreadid; (* threadid *)

(*this function just pronts the passed array.*)
function miniexp(pt : pointer) : ptrint;
var
  toPrint : TByteArray;
  idx : TArrIndex;
begin
  toPrint :=  PByteArray(pt)^;

  for idx := low(toPrint) to high(toPrint) do
  begin
     writeln(toPrint[idx]);
  end;

   miniexp := 0;
  // EndThread;
end;
 
Begin
  SetLength(AnArray, 10); (*set array to proper length*)

  (* fill the array*)
  randomize;
   for lc := low(AnArray) to high(AnArray) do
   begin
      AnArray[lc] := (random(521) mod 256);
   end; 
 
   (*The following works, but does'nt pass the full array. *)
    ArrAddr := @AnArray;
    thid := BeginThread(TThreadfunc(@miniexp), pointer(ArrAddr));
    WaitForThreadTerminate(thid, 1000000);
   
   
End.
--- End code ---

I commented EndThread; in the function. With EndThread; it worked too but it gave a memory leak.
Also correction in this line:

--- Code: --- toPrint :=  PByteArray(pt)^;
--- End code ---

User137:

--- Code: ---type
  TByteArray = Array of Byte;
  //PByteArray = ^TByteArray;
--- End code ---
This may simplify the idea a little, you know the TByteArray is already a pointer because it is dynamic array.

If you do:

--- Code: ---var arr: TByteArray;
begin
  setlength(add, 99999999999);
  someFunc(arr);
--- End code ---
It will only pass a pointer to someFunc(). (No data is copied for parameter.)

marcov:

--- Quote from: Blaazen on June 12, 2014, 09:06:50 pm ---Your code compiles here (FPC 2.7.1), with only a small change:

--- End quote ---

Your code is unsafe, relying on implementation dependent features:


--- Code: --- 
   (*The following works, but does'nt pass the full array. *)
    ArrAddr := @AnArray;
    thid := BeginThread(TThreadfunc(@miniexp), pointer(ArrAddr));

--- End code ---

At this point miniexp can be deallocated, while the new thread might still access it.

--- Code: ---    WaitForThreadTerminate(thid, 1000000);

--- End code ---
   

Navigation

[0] Message Index

Go to full version