线程是操作系统能够进行运算调度的最小单位,是进程中的实际运作单元。一个进程可以包含多个线程,所有线程共享进程的内存空间和系统资源,但每个线程有自己的栈和程序计数器。
主要特点:
现象:程序行为因线程执行顺序不同而变化
// 示例:未同步的计数器
int counter = 0;
void* increment(void* arg) {
for (int i = 0; i < 100000; i++) {
counter++; // 非原子操作
}
return NULL;
}
解决方案:
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
void* safe_increment(void* arg) {
for (int i = 0; i < 100000; i++) {
pthread_mutex_lock(&lock);
counter++;
pthread_mutex_unlock(&lock);
}
return NULL;
}
现象:多个线程互相等待对方释放资源
// 两个锁的错误使用
pthread_mutex_t lockA = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t lockB = PTHREAD_MUTEX_INITIALIZER;
void* thread1(void* arg) {
pthread_mutex_lock(&lockA);
pthread_mutex_lock(&lockB); // 可能阻塞
// ...
pthread_mutex_unlock(&lockB);
pthread_mutex_unlock(&lockA);
}
void* thread2(void* arg) {
pthread_mutex_lock(&lockB);
pthread_mutex_lock(&lockA); // 可能阻塞
// ...
pthread_mutex_unlock(&lockA);
pthread_mutex_unlock(&lockB);
}
解决方案:
现象:某些线程长期得不到执行机会 调试工具:
top -H
(Linux查看线程CPU占用)info threads
命令#define THREAD_DEBUG(fmt, ...) \
printf("[%lu] " fmt "\n", pthread_self(), ##__VA_ARGS__)
valgrind --tool=helgrind ./your_program
gcc -fsanitize=thread -g your_program.c
// C++11示例
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx;
void print_thread_id(int id) {
mtx.lock();
std::cout << "Thread #" << id << '\n';
mtx.unlock();
}
int main() {
std::thread threads[5];
for (int i=0; i<5; ++i)
threads[i] = std::thread(print_thread_id, i+1);
for (auto& th : threads) th.join();
return 0;
}
通过系统理解线程原理、掌握调试工具和遵循最佳实践,可以有效地开发和调试多线程应用程序。
没有搜到相关的文章