线程挂起情况

线程挂起
定义:线程挂起(suspended)是指线程在执行过程中被暂停,无法继续运行。挂起的线程通常处于一种非活动状态,等待某个条件或事件的发生。
原因:线程可能因多种原因挂起,例如:
主动调用挂起函数(如 pthread_suspend,虽然在POSIX标准中并不直接支持)。
等待某个资源(如锁、信号量、条件变量等)。
被操作系统调度器挂起,以便让其他线程或进程运行。

被其他进程阻塞
定义:当一个线程被其他进程阻塞时,意味着该线程无法继续执行,因为它正在等待某个资源或条件,而该资源或条件被其他进程占用。
原因:线程被阻塞的常见原因包括:
资源竞争:线程试图访问一个被其他线程或进程占用的共享资源(如互斥锁、读写锁等)。
I/O 操作:线程在执行输入输出操作时,可能会被阻塞,直到I/O操作完成。
等待信号:线程可能在等待某个信号或事件的发生(如条件变量的通知)。

示例
假设有两个线程 A 和 B,线程 A 试图获取一个锁,而线程 B 已经持有该锁。此时,线程 A 将被阻塞,直到线程 B 释放锁。线程 A 可能会处于挂起状态,等待资源的可用性。

以下是一个简单的示例,展示了线程挂起和被其他进程阻塞的情况。我们将使用 POSIX 线程(pthread)库来创建和管理线程。

示例代码
这个示例中,我们将创建两个线程:一个线程尝试获取一个互斥锁,而另一个线程持有该锁并进行长时间的处理。第一个线程将被阻塞,直到第二个线程释放锁。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

pthread_mutex_t lock;

void *thread_function1(void *arg) {
   printf("Thread 1: Trying to acquire the lock...\n");
   pthread_mutex_lock(&lock); // 尝试获取锁
   printf("Thread 1: Acquired the lock!\n");

   // 模拟长时间的处理
   sleep(2);
   printf("Thread 1: Releasing the lock...\n");
   pthread_mutex_unlock(&lock); // 释放锁
   return NULL;
}

void *thread_function2(void *arg) {
   printf("Thread 2: Acquiring the lock...\n");
   pthread_mutex_lock(&lock); // 获取锁
   printf("Thread 2: Acquired the lock! Doing some work...\n");

   // 模拟长时间的处理
   sleep(5);
   printf("Thread 2: Finished work, releasing the lock...\n");
   pthread_mutex_unlock(&lock); // 释放锁
   return NULL;
}

int main() {
   pthread_t thread1, thread2;

   // 初始化互斥锁
   pthread_mutex_init(&lock, NULL);

   // 创建线程
   pthread_create(&thread2, NULL, thread_function2, NULL);
   sleep(1); // 确保线程2先运行
   pthread_create(&thread1, NULL, thread_function1, NULL);

   // 等待线程结束
   pthread_join(thread1, NULL);
   pthread_join(thread2, NULL);

   // 销毁互斥锁
   pthread_mutex_destroy(&lock);
   return 0;
}

代码说明:
互斥锁:使用 pthread_mutex_t 创建一个互斥锁,确保线程之间的互斥访问。
线程1:尝试获取锁并在获取成功后进行处理。它在处理完成后释放锁。
线程2:在创建时立即获取锁并进行长时间的处理。由于它持有锁,线程1将被阻塞,直到线程2释放锁。
睡眠:在创建线程1之前,主线程睡眠1秒,以确保线程2有机会先运行并获取锁。
线程同步:使用 pthread_join 等待两个线程完成。

运行结果
当您运行这个程序时,您将看到如下输出:

Thread 2: Acquiring the lock...
Thread 2: Acquired the lock! Doing some work...
Thread 1: Trying to acquire the lock...
Thread 1: (blocked) // 线程1在这里被阻塞,直到线程2释放锁
Thread 2: Finished work, releasing the lock...
Thread 1: Acquired the lock!
Thread 1: Releasing the lock...

总结
在这个示例中,线程1尝试获取一个被线程2持有的锁,因此它被阻塞,直到线程2释放锁。这个过程展示了线程挂起和被其他进程阻塞的概念。

展示了如何使用条件变量来实现线程的挂起,直到接收到信号(通知)后才继续执行。我们将使用 POSIX 线程(pthread)库来创建和管理线程。

示例代码
在这个示例中,我们将创建两个线程:一个线程将等待信号(条件变量),而另一个线程将在稍后发送信号,通知第一个线程继续执行。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

pthread_mutex_t mutex;
pthread_cond_t cond_var;
int ready = 0; // 用于指示是否可以继续

void *waiting_thread(void *arg) {
   printf("Waiting thread: Waiting for signal...\n");

   // 锁定互斥锁
   pthread_mutex_lock(&mutex);
   
   // 等待条件变量的信号
   while (ready == 0) {
       pthread_cond_wait(&cond_var, &mutex); // 线程挂起,等待信号
   }

   // 收到信号后继续执行
   printf("Waiting thread: Received signal, continuing execution...\n");

   // 解锁互斥锁
   pthread_mutex_unlock(&mutex);
   return NULL;
}

void *signaling_thread(void *arg) {
   sleep(2); // 模拟一些工作
   printf("Signaling thread: Sending signal...\n");

   // 锁定互斥锁
   pthread_mutex_lock(&mutex);
   
   // 修改状态并发送信号
   ready = 1;
   pthread_cond_signal(&cond_var); // 发送信号,唤醒等待的线程

   // 解锁互斥锁
   pthread_mutex_unlock(&mutex);
   return NULL;
}

int main() {
   pthread_t thread1, thread2;

   // 初始化互斥锁和条件变量
   pthread_mutex_init(&mutex, NULL);
   pthread_cond_init(&cond_var, NULL);

   // 创建线程
   pthread_create(&thread1, NULL, waiting_thread, NULL);
   pthread_create(&thread2, NULL, signaling_thread, NULL);

   // 等待线程结束
   pthread_join(thread1, NULL);
   pthread_join(thread2, NULL);

   // 销毁互斥锁和条件变量
   pthread_mutex_destroy(&mutex);
   pthread_cond_destroy(&cond_var);
   return 0;
}

代码说明:
互斥锁和条件变量:使用 pthread_mutex_t 和 pthread_cond_t 创建互斥锁和条件变量。
等待线程:waiting_thread 函数在执行时会锁定互斥锁,然后调用 pthread_cond_wait 等待条件变量的信号。在等待期间,线程会被挂起,直到接收到信号。
信号线程:signaling_thread 函数在模拟一些工作后,锁定互斥锁,修改状态并调用 pthread_cond_signal 发送信号,唤醒等待的线程。
主线程:创建两个线程并等待它们完成。
运行结果
当您运行这个程序时,您将看到如下输出:

Waiting thread: Waiting for signal...
Signaling thread: Sending signal...
Waiting thread: Received signal, continuing execution...

在这个示例中,waiting_thread 线程因为等待条件变量的信号而挂起,直到 signaling_thread 发送信号。这个过程展示了由于等待信号导致的线程挂起的概念。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值