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 3976268
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 20, 20262026-05-20T04:47:03+00:00 2026-05-20T04:47:03+00:00

Borrowing Howard Hinnant’s example and modifying it to use copy-and-swap, is this op= thread-safe?

  • 0

Borrowing Howard Hinnant’s example and modifying it to use copy-and-swap, is this op= thread-safe?

struct A {
  A() = default;
  A(A const &x);  // Assume implements correct locking and copying.

  A& operator=(A x) {
    std::lock_guard<std::mutex> lock_data (_mut);
    using std::swap;
    swap(_data, x._data);
    return *this;
  }

private:
  mutable std::mutex _mut;
  std::vector<double> _data;
};

I believe this thread-safe (remember op=’s parameter is passed by value), and the only problem I can find is the one swept under the rug: the copy ctor. However, it would be a rare class that allows copy-assignment but not copy-construction, so that problem exists equally in both alternatives.

Given that self-assignment is so rare (at least for this example) that I don’t mind an extra copy if it happens, consider the potential optimization of this != &rhs to be either negligible or a pessimization. Would there be any other reason to prefer or avoid it compared to the original strategy (below)?

A& operator=(A const &rhs) {
  if (this != &rhs) {
    std::unique_lock<std::mutex> lhs_lock(    _mut, std::defer_lock);
    std::unique_lock<std::mutex> rhs_lock(rhs._mut, std::defer_lock);
    std::lock(lhs_lock, rhs_lock);
    _data = rhs._data;
  }
  return *this;
}

Incidentally, I think this succinctly handles the copy ctor, at least for this class, even if it is a bit obtuse:

A(A const &x) : _data {(std::lock_guard<std::mutex>(x._mut), x._data)} {}
  • 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-05-20T04:47:04+00:00Added an answer on May 20, 2026 at 4:47 am

    I believe your assignment is thread safe (assuming of course no references outside the class). The performance of it relative to the const A& variant probably depends on A. I think for many A that your rewrite will be just as fast if not faster. The big counter-example I have is std::vector (and classes like it).

    std::vector has a capacity that does not participate in its value. And if the lhs has sufficient capacity relative to the rhs, then reusing that capacity, instead of throwing it away to a temp, can be a performance win.

    For example:

    std::vector<int> v1(5);
    std::vector<int> v2(4);
    ...
    v1 = v2;
    

    In the above example, if v1 keeps its capacity to do the assignment, then the assignment can be done with no heap allocation or deallocation. But if vector uses the swap idiom, then it does one allocation and one deallocation.

    I note that as far as thread safety goes, both algorithms lock/unlock two locks. Though the swap variant avoids the need to lock both of them at the same time. I believe on average the cost to lock both at the same time is small. But in heavily contested use cases it could become a concern.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Borrowing from the example on the Matplotlib documentation page and slightly modifying the code,
I am borrowing this code that was entering strings (user, message) into shoutbox table
I'm borrowing/adapting this simple html/javascript form set up to put some data in the
I'm borrowing the slice meaning from C++. Let's say I hava a simple POJO
I am borrowing some codeigniter authentication library and try to integrate it with my
I'm borrowing a rather complex regex from some PHP Textile implementations (open source, properly
I see lots of php libraries that can parse html. A nice example is
Currently I am borrowing java.math.BigInteger from the J# libraries as described here . Having
Most languages use the true/false keywords for boolean values. I found that even Smalltalk
I am making a table that will be borrowing a couple of columns from

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.