2

I'm a little bit lost in multithreading application I'm analysing. I supposed that function I'm trying to understand acts in main thread. To be sure I have placed enter and exit critical section code in it. The same critical section is also used in program startup (enter critical section) and termination (leave critical section).

Correct me if I'm wrong. If my function acts in main thread, critical section should allow to be entered. But it is not so - my functions just stops on entering critical section. According to my understanding this function acts in another thread.

Is my method correct for understanding which function acts in which thread?

Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
vico
  • 17,051
  • 45
  • 159
  • 315
  • 1
    You are right, but logging is more simple and informative. – kludg Aug 28 '12 at 16:34
  • 4
    To check if your code is executing in the main thread use : `Windows.GetCurrentThreadId() = System.MainThreadID`. See [What is function in Delphi to get the current executing thread?](http://stackoverflow.com/q/155560/576719). – LU RD Aug 28 '12 at 16:34
  • 1) Why you put the whole program inside a critical section? 2) Why you do not accept an answer for your previous questions? – Marcelo De Zen Aug 28 '12 at 16:37
  • @devundef I have on idea why some of mine questions are not accepted. Usually I press acceptance tick and it becomes green, but in my activity log just some of questions are marked as accepted. – vico Aug 29 '12 at 10:10

3 Answers3

4

Just use the debugger. Set a breakpoint in the startup code of your app, or in any message handler in your app, and check the current thread id in the debugger threads window. Then set a breakpoint in the function in question, and check the thread id when execution reaches that function. If they don't match, then the function is not being called on the same thread that your UI messages are running on.

While you're stopped in your function in the debugger, you can take a look at the call stack window to see the sequence of calls that led to your function call. This may provide some insight into how you got there, and how you got there on a different thread.

dthorpe
  • 35,318
  • 5
  • 75
  • 119
0

I believe you are using critical sections in the wrong way. Imagine you have a variable that might be modified in your main thread as well as other threads. Each time you want to access this variable, you first Acquire the critical section; like this:

if MyCriticalSection.TryEnter then  // MyVariable is accessible
begin
  MyVariable := MyVariable + 1;
  MyCriticalSection.Release;
end
else begin
  // do something useful and try again in a few milliseconds.
end;

Remember, when you call Acquire, the calling thread will be frozen until the critical section is available. So, if you are calling Acquire at the beginning of your application, the second call to it will freeze your main thread.

iMan Biglari
  • 4,674
  • 1
  • 38
  • 83
0

You can't lock it inside main thread. Always use the critical section in threads. Declare cs:TRTLCriticalSection as global var. Call any thread. Lock and unlock the cs inside a execute procedure not in main thread or not in the create constructor in thread.

Also you cant read the cnt variable inside main thread. But Synchronize method update the mainCnt variable for reading it inside a main thread

var //global
  cs :TRTLCriticalSection;
  cnt:integer;  //use it only inside thread
  mainCnt:integer; //same value for cnt. use it inside a main thread.

///formcreate..
begin
  InitializeCriticalSection(cs);

///formdestroy
  DeleteCriticalSection(cs);

type
  TThrInc = class(TThread)
  private
    fAnyParam:Integer;
  protected
    procedure Execute; override;
  public
    constructor Create(anyparam:integer);
  end;


constructor TThrInc.Create(anyparam:integer);
begin
  fAnyParam:=AnyParam;  //you dont need this
end;

procedure TThrInc.execute;
var tmpcnt:integer;
begin
  EnterCriticalSection(cs);
  try begin
    inc(cnt);
    tmpcnt:=cnt;
  end except end;
  LeaveCriticalSection(cs);

  Synchronize(
    procedure
    begin
      mainCnt:=tmpcnt;
    end);
end;
andreas
  • 16,357
  • 12
  • 72
  • 76
ehuehu
  • 1
  • 1