执行中的线程顺序

JAN*_*JAN 6 c++ multithreading visual-studio visual-studio-2012

考虑这个简单的并发示例:

#include <iostream>       // std::cout
#include <thread>         // std::thread
#include <mutex>          // std::mutex

std::mutex mtx;           // mutex for critical section

void print_block(int n, char c) {
    // critical section (exclusive access to std::cout signaled by locking mtx):
    mtx.lock();
    for (int i = 0; i<n; ++i) { std::cout << c; }
    std::cout << '\n';
    mtx.unlock();
}

int main()
{
    std::thread th1(print_block, 50, '*');
    std::thread th2(print_block, 50, '$');

    th1.join();
    th2.join();

    return 0;
} 
Run Code Online (Sandbox Code Playgroud)

是否始终保证th1将成为执行for循环的第一个线程?

意思是,当我这样做时:

th1.join();
th2.join();
Run Code Online (Sandbox Code Playgroud)

那么我可以绝对肯定th1会先执行th2吗?

bku*_*ytt 6

不,你最有可能看到th1总是首先开始,因为该变量的线程构造首先完成(并且线程构造很昂贵),因此th2开始之后.这并不意味着有订单.

调用join()与首先执行哪个线程没有任何关系,这是在你提供可调用时在构造时完成的.

th1可以构造然后由OS停止,这将导致th2首先运行.除非您实施,否则没有订单.

考虑这个例子,它给两个线程提供了更公平的启动,它有时输出线程1作为第一个获取锁,它有时输出线程2.

例:

#include <iostream>         // std::cout
#include <string>           // std::string
#include <unordered_map>    // std::unordered_map<K, V>
#include <thread>           // std::thread
#include <mutex>            // std::mutex
#include <atomic>           // std::atomic<T>

std::unordered_map<std::thread::id, std::string> thread_map;
std::mutex mtx;           // mutex for critical section
std::atomic<bool> go{ false };

void print_block( int n, char c )
{
    while ( !go ) {} // prevent threads from executing until go is set.
    // critical section (exclusive access to std::cout signaled by locking mtx):
    mtx.lock();

    std::cout << thread_map.find( std::this_thread::get_id() )->second <<
        " acquires the lock.\n";

    mtx.unlock();
}

int main()
{
    std::thread th1( print_block, 50, '*' );
    std::thread th2( print_block, 50, '$' );

    thread_map.emplace( std::make_pair( th1.get_id(), "Thread 1" ) );
    thread_map.emplace( std::make_pair( th2.get_id(), "Thread 2" ) );

    go.store( true );

    th1.join();
    th2.join();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • @ron获取锁没有竞争条件,锁是线程安全的.如果你的字面意思是两个线程将竞争获得锁定,那么是; 这就是为什么它更公平.我们等到两个线程都完成了它们的构造,然后才让它们为锁定而战.如果您执行我的示例,您将看到有时线程2在线程1之前获取锁定. (2认同)