商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > 如何在Linux上使用C++进行多线程编程

如何在Linux上使用C++进行多线程编程

  发布于2026-07-20 阅读(0)

扫一扫,手机访问

在Linux上搞C++多线程,其实没那么玄乎。从C++11开始,标准库直接提供了头文件,意味着你不需要再折腾那些底层的POSIX线程API了。下面就把常用的几个步骤和模式拆开讲讲,边看代码边理解,上手会快很多。

安装必要的工具

动手之前,先确认系统里有没有装好GCC编译器和GDB调试器。大多数Linux发行版默认不带开发工具,所以可以跑一下这两条命令:

sudo apt-get update
sudo apt-get install build-essential gdb

装完就算准备好环境了。

编写多线程程序

来看一个最简单的例子——创建一个线程,让它打个招呼,然后主线程等着它结束。代码非常直观:

#include 
#include 

void helloFunction() {
    std::cout << "Hello from a thread!" << std::endl;
}

int main() {
    std::thread t(helloFunction);
    t.join();
    std::cout << "Hello from the main thread!" << std::endl;
    return 0;
}

这里join()的作用就是让主线程停住,等子线程跑完再继续往下走。如果不等,主线程可能直接结束,导致子线程还没来得及输出就被强制终止了。

编译程序

编译时记得加两个参数:指定C++11标准(或更高),以及链接pthread库。命令长这样:

g++ -std=c++11 -pthread your_program.cpp -o your_program

注意那个-pthread,少了它链接会报错,因为C++的线程库底层还是依赖POSIX线程的。

运行程序

编译成功后的可执行文件直接跑:

./your_program

输出应该能看到两行“Hello”,顺序不一定,但主线程那行肯定在子线程之后——因为join保证了这一点。

多线程同步

实际场景里,多个线程往往要操作同一个数据,比如打印消息、更新计数器。这时候没有锁就会乱套。C++11提供了std::mutex,用法很简单:

#include 
#include 
#include 

std::mutex mtx;

void printMessage(const std::string& msg) {
    mtx.lock();
    std::cout << msg << std::endl;
    mtx.unlock();
}

int main() {
    std::thread t1(printMessage, "Hello from thread 1!");
    std::thread t2(printMessage, "Hello from thread 2!");
    t1.join();
    t2.join();
    return 0;
}

每个线程在输出前先抢锁,抢到之后独占输出,保证两条消息不会混在一起。不过手动lock/unlock容易忘,推荐用std::lock_guard自动管理,但这里只是展示最朴素的写法。

使用条件变量

条件变量适合一种场景:一个线程要等另一个线程准备好某些条件再开始干活。比如下面这个例子,工作线程一直等着,直到主线程把ready设为true并通知它:

#include 
#include 
#include 
#include 

std::mutex mtx;
std::condition_variable cv;
bool ready = false;

void workerThread() {
    std::unique_lock lock(mtx);
    cv.wait(lock, []{ return ready; });
    std::cout << "Worker thread is processing data..." << std::endl;
}

int main() {
    std::thread worker(workerThread);

    // 主线程准备数据
    {
        std::lock_guard lock(mtx);
        ready = true;
    }
    cv.notify_one();

    worker.join();
    return 0;
}

这里的关键是cv.wait会阻塞线程,同时释放锁;等到被通知后,它会重新获取锁并检查条件(lambda表达式)。如果条件不满足,它会继续等待,避免虚假唤醒的问题。

使用原子操作

如果只是简单的计数器累加,用锁显得有点重。C++11的std::atomic可以做到无锁的原子操作,性能更好。看一个例子:两个线程各自对同一个原子变量加10万次,最终结果一定是20万:

#include 
#include 
#include 

std::atomic counter(0);

void incrementCounter() {
    for (int i = 0; i < 100000; ++i) {
        counter++;
    }
}

int main() {
    std::thread t1(incrementCounter);
    std::thread t2(incrementCounter);
    t1.join();
    t2.join();
    std::cout << "Counter value: " << counter << std::endl;
    return 0;
}

注意counter++这个操作在原子变量上本身就是线程安全的,不需要额外加锁。当然,原子操作只适合简单的整型或指针,复杂的共享数据结构还是得靠互斥锁。

这几个例子基本覆盖了C++多线程编程的常见场景:创建线程、同步、条件等待、原子操作。掌握了这些,后面再去看线程池、任务队列那些进阶内容,思路会清晰很多。实际开发中,记得多考虑异常安全和死锁问题,多写测试,慢慢就能写出健壮的多线程程序了。

本文转载于:https://www.yisu.com/ask/69231651.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注