在Linux中,线程主动切换主要有以下几种方法:
一、基于条件变量(pthread_cond_wait / pthread_cond_signal)
pthread_cond_wait
进入等待状态,此时线程会释放它所持有的互斥锁(通常与条件变量一起使用来保护共享数据),并进入阻塞状态。当另一个线程使条件满足时,它可以调用pthread_cond_signal
或者pthread_cond_broadcast
来唤醒等待的线程。pthread_cond_signal
只会唤醒一个等待线程,而pthread_cond_broadcast
会唤醒所有等待线程。pthread_cond_wait
);消费者线程消费数据,当缓冲区空时,消费者线程等待。当生产者生产了新的数据或者消费者消费了数据后,通过pthread_cond_signal
或pthread_cond_broadcast
来通知等待的线程。#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
pthread_mutex_t mutex;
pthread_cond_t cond;
int data = 0;
void* producer(void* arg) {
for (int i = 0; i < 5; i++) {
pthread_mutex_lock(&mutex);
while (data == 1) {
pthread_cond_wait(&cond, &mutex);
}
data = 1;
printf("Producer produced data
");
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
sleep(1);
}
return NULL;
}
void* consumer(void* arg) {
for (int i = 0; i < 5; i++) {
pthread_mutex_lock(&mutex);
while (data == 0) {
pthread_cond_wait(&cond, &mutex);
}
data = 0;
printf("Consumer consumed data
");
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
sleep(1);
}
return NULL;
}
int main() {
pthread_t producer_thread, consumer_thread;
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);
pthread_create(&producer_thread, NULL, producer, NULL);
pthread_create(&consumer_thread, NULL, consumer, NULL);
pthread_join(producer_thread, NULL);
pthread_join(consumer_thread, NULL);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
return 0;
}
二、基于信号量(semaphore)
#include <semaphore.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
sem_t sem;
int shared_data = 0;
void* thread1(void* arg) {
for (int i = 0; i < 3; i++) {
sem_wait(&sem);
shared_data++;
printf("Thread1: shared_data = %d
", shared_data);
sem_post(&sem);
sleep(1);
}
return NULL;
}
void* thread2(void* arg) {
for (int i = 0; i < 3; i++) {
sem_wait(&sem);
shared_data--;
printf("Thread2: shared_data = %d
", shared_data);
sem_post(&sem);
sleep(1);
}
return NULL;
}
int main() {
pthread_t t1, t2;
sem_init(&sem, 0, 1);
pthread_create(&t1, NULL, thread1, NULL);
pthread_create(&t2, NULL, thread2, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
sem_destroy(&sem);
return 0;
}
三、主动让出CPU(sched_yield)
sched_yield
函数允许当前线程主动让出CPU资源,使得调度器可以调度其他就绪状态的线程运行。这并不一定会导致线程进入阻塞状态,只是让出当前的CPU时间片。sched_yield
来优化系统的调度。#include <sched.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
void* thread_func(void* arg) {
for (int i = 0; i < 5; i++) {
printf("Thread running iteration %d
", i);
sched_yield();
sleep(1);
}
return NULL;
}
int main() {
pthread_t thread;
pthread_create(&thread, NULL, thread_func, NULL);
pthread_join(thread, NULL);
return 0;
}
四、线程休眠(sleep / usleep)
sleep
函数使当前线程暂停执行指定的秒数,usleep
使线程暂停执行指定的微秒数。这是一种简单的让线程主动停止执行一段时间的方法,在这段时间内,线程会让出CPU资源给其他线程。#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
void* thread_func(void* arg) {
for (int i = 0; i < 3; i++) {
printf("Thread sleeping iteration %d
", i);
sleep(2);
}
return NULL;
}
int main() {
pthread_t thread;
pthread_create(&thread, NULL, thread_func, NULL);
pthread_join(thread, NULL);
return 0;
}
如果遇到线程切换相关的问题:
一、死锁问题(可能与线程切换机制相关)
二、线程饥饿问题
领取专属 10元无门槛券
手把手带您无忧上云