Sharing data with another thread using lock_guard
Yes, that all looks correct to me!

You don't use anything from &lt;unistd.h&gt; (non-standard) or &lt;initializer_list&gt; (obscure), so I recommend removing those includes.



You sigil the mutex_ data member with an underscore, but you don't sigil the v member. I recommend being consistent:

std::mutex mutex_;
std::vector&lt;int&gt; v_;


Personally I would spell the member's name mtx_, but that's just a personal habit; I don't know if that naming convention is widespread. (cv_ for a condition variable certainly is, though!)



Consider that your Check and dump methods don't need to mutate the object, so they should be declared const. This means that your mutex_ data member will need to be declared mutable so that you can still lock and unlock it inside your const member functions.

Also, consider picking a capitalization rule and sticking to it. Why Check and Update but dump (not Dump)?

Check's parameter x is marked const but that marking serves no purpose: eliminate it. (Const is a contract.)



for (int i = 0; i &lt; v.size(); i++) {
    if (!g_c.Check(v[i])){
        std::cout &lt;&lt;  v[i] &lt;&lt; " ";
    }
}


This could be rewritten more concisely as

for (int vi : v) {
    if (!g_c.Check(vi)) {
        std::cout &lt;&lt; vi &lt;&lt; " ";
    }
}


Your multithreading stuff all looks great!