Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8931915
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 15, 20262026-06-15T09:13:10+00:00 2026-06-15T09:13:10+00:00

I am trying to utilize shared function (in main thread) and use it from

  • 0

I am trying to utilize shared function (in main thread) and use it from 3 threads. The function will do some potentially lengthy operation like disk write and to avoid possible problems I will lock it. I use Indy IdThreadComponent and TCriticalSection. Here is how it looks:

//---------------------------------------------------------------------------
// In header file
//---------------------------------------------------------------------------
boost::scoped_ptr<TCriticalSection> csShared;

//---------------------------------------------------------------------------
// Main file
//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
csShared.reset(new TCriticalSection);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SharedFunction(UnicodeString TextData)
{
try
    {
    csShared->Enter();           // As suggested by Remy this is placed incorrectly and needs to be moved outside of try block
    //Memo1->Lines->Add(TextData); // [EDIT] calling this within thread is wrong
    Sleep(2000);
    }
__finally
    {
    csShared->Leave();
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdThreadComponent1Run(TIdThreadComponent *Sender)
{
SharedFunction("Thread 1 calling");
IdThreadComponent1->Stop();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdThreadComponent2Run(TIdThreadComponent *Sender)
{
SharedFunction("Thread 2 calling");
IdThreadComponent2->Stop();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdThreadComponent3Run(TIdThreadComponent *Sender)
{
SharedFunction("Thread 3 calling");
IdThreadComponent3->Stop();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
IdThreadComponent1->Start();
IdThreadComponent2->Start();
IdThreadComponent3->Start();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCloseQuery(TObject *Sender, bool &CanClose)
{
// Note - these 3 Stop() calls are used if threads are set to run infinitely
// But in this example it is not needed as they stop themselves
//IdThreadComponent1->Stop();
//IdThreadComponent2->Stop();
//IdThreadComponent3->Stop();

// Now wait for lock to be released [WRONG - COMMENTED IN EDIT]
//while (!csShared->TryEnter())
//  {
//  Sleep(500);
//  }
//csShared->Leave();

// [EDIT v1] easier and faster way to wait than above
//csShared->Enter();
//csShared->Leave();

// [EDIT v2] block exit until all threads are done
while (IdThreadComponent1->Active || IdThreadComponent2->Active || IdThreadComponent3->Active)
{
Sleep(200); // make wait loop less CPU intensive
};

CanClose = true;
}
//---------------------------------------------------------------------------

The problems:

– If I close window quickly (only one thread executes the function, it never leaves program – waits forever, and in debugger only first thread exits, other two don’t). I am using OnCloseQuery event to check if threads are done. What I am doing wrong?

[EDIT] After removing Memo1->Lines->Add(TextData); as suggested in comments by David Heffernan, it exits properly so this part of question is solved and the following remains:

  • Is it fine to call csShared->Enter(); inside the shared function like above or do I have to call it outside of it in each thread like this:

    void __fastcall TForm1::IdThreadComponent1Run(TIdThreadComponent *Sender)
    {
    csShared->Enter();
    SharedFunction("Thread 1 calling");
    csShared->Leave();
    IdThreadComponent1->Stop();
    }
    
  • Is this better than the above version (calling csShared->Enter(); within the function itself)? Or the same? Both versions seem to work fine, I am wondering is there a difference, because the first one is cleaner.

I do not need Synchronize in case if you are wondering, this will be for disk write and not for updating VCL, so the above SharedFunction is just for the example purpose.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-15T09:13:11+00:00Added an answer on June 15, 2026 at 9:13 am

    It is fine, even desirable, to put the calls to Enter() and Leave() inside of the shared function. However, if you are going to use try/__finally then you need to put the Enter() outside of the try, in case it fails. You don’t want to Leave() something you did not successful Enter() into, eg:

    void __fastcall TForm1::SharedFunction(UnicodeString TextData)
    {
        csShared->Enter();
        try
        {
            //...
            Sleep(2000);
        }
        __finally
        {
            csShared->Leave();
        }
    }
    
    void __fastcall TForm1::IdThreadComponent1Run(TIdThreadComponent *Sender)
    {
        SharedFunction("Thread 1 calling");
        IdThreadComponent1->Stop();
    }
    

    Since you are using Boost anyway, you should make use of its own mutex and lock classes instead, then you don’t have to worry about try/__finally, Enter(), or Leave() at all, eg:

    #include <boost/thread/recursive_mutex.hpp>
    #include <boost/thread/locks.hpp>
    
    boost::recursive_mutex mutex;
    
    void __fastcall TForm1::SharedFunction(UnicodeString TextData)
    {
        boost::lock_guard<boost::recursive_mutex> lock(mutex);
        //...
        Sleep(2000);
    }
    

    As for the TMemo access, use the TIdSync or TIdNotify class to execute that code in a thread-safe manner, eg:

    #include <IdSync.hpp>
    
    class TMemoNotify : public TIdNotify
    {
    protected:
        String TextData;
    
        void __fastcall DoNotify()
        {
            Form1->Memo1->Lines->Add(TextData);
        }
    
    public:
        __fastcall TMemoNotify(const String &ATextData) : TextData(ATextData) {}
    };
    
    
    void __fastcall TForm1::SharedFunction(UnicodeString TextData)
    {
        ...
        (new TMemoNotify(TextData))->Notify(); // TIdNotify is self-freeing
        ...
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm trying to utilize Boost.Test in Visual Studio 2010, and I'm having some trouble
I'm trying to utilize a row and a column header to build a function
I'm trying to utilize a class from the Google Toolbox for Mac libraries, for
I'm trying to utilize compass/sass/960 grid system. However, it doesn't seem like compass-960-plugin is
I have been migrating from Windows Forms to WPF and am trying to utilize
I'm trying to utilize the RadScheduler component from Telerik for a public facing website,
I'm trying to think how should I utilize threads in my program. Right now
I've been trying to utilize a mail.php file from the jquery contactable plugin (found
I am trying to utilize Numpy's fft function, however when I give the function
I am trying to utilize the NSNotificationCenter and for some reason the selector method

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.