在 C Linux 中使用三个线程使用信号量同步按顺序打印 3 4 5 50 次

print 3 4 5 in sequence for 50 times using semaphore synchronization using three threads in C Linux

本文关键字:打印 顺序 同步 信号量 三个 Linux 线程      更新时间:2023-10-16

我的编程陷入死锁。我正在尝试使用信号量同步使用三个线程按顺序打印三个数字 3 4 5 50 次。 请帮助我。

下面是代码

#include <iostream>
#include <pthread.h>
#include <semaphore.h>
using namespace std;
sem_t sem1;
sem_t sem2;
sem_t sem3;
void * fun1(void *)
{   
for(int i = 0; i < 50 ; i++)
{
sem_wait(&sem1);
sem_wait(&sem3);
cout<<"3"
sem_post(&sem2);
sem_post(&sem3);
}
}

void * fun2(void *)
{   
for(int i = 0; i < 50 ; i++)
{
sem_wait(&sem2);
sem_wait(&sem3);
cout<<"4";
sem_post(&sem3);
sem_post(&sem1);
}
}
void * fun3 (void *)
{
for(int i = 0; i< 50; i++)
{
sem_wait(&sem2);
sem_wait(&sem3);
cout<<"5";
sem_post(&sem1);
sem_post(&sem2);
}
}
int main()
{
pthread_t t1;
pthread_t t2;
pthread_t t3;

sem_init(&sem1,0,1);
sem_init(&sem2,0,0);
sem_init(&sem3,0,1);
pthread_create(&t1,NULL,&fun1,NULL);
pthread_create(&t2,NULL,&fun2,NULL);
pthread_create(&t3,NULL,&fun3,NULL); 
pthread_join(t1,NULL);
pthread_join(t2,NULL);
pthread_join(t3,NULL);
return 1;
}

请帮助我理解并解决这个僵局。提供建议,我也可以这样做,例如使用 3 个线程的 3 4 5 6 个线程

请帮助我理解并解决这个僵局。

您的代码中确实存在死锁。考虑一开始,线程 1 首先获得 2 个信号量并调用cout << "3"。发布sem2sem3后,线程 3 可能会立即获得这 2 个 sem,然后调用cout << "5"。但是,在线程 3 发布sem1sem2后,没有人能达成cout <<语句,因为sem3的值是 0,每个人都需要通过等待sem3

如果您想知道为什么完全没有输出,那是因为内部的缓冲区iostream.对于控制台输出,"n"将刷新缓冲区,因此如果将"3"替换为"3n",则可以看到输出。

提供建议,我也可以这样做,例如使用 3 个线程的 3 4 5 6 个线程

在下面的代码中,您应该看到对称性,它可以很容易地推广到任意数量的线程。并且您应该始终在使用信号量后调用sem_destroy,否则您可能会遇到系统级资源泄漏。

#include <iostream>
#include <pthread.h>
#include <semaphore.h>
using namespace std;
sem_t sem1;
sem_t sem2;
sem_t sem3;
void * fun1(void *)
{   
for(int i = 0; i < 50 ; i++)
{
sem_wait(&sem1);
cout<<"3n";
sem_post(&sem2);
}
}

void * fun2(void *)
{   
for(int i = 0; i < 50 ; i++)
{
sem_wait(&sem2);
cout<<"4n";
sem_post(&sem3);
}
}
void * fun3 (void *)
{
for(int i = 0; i< 50; i++)
{
sem_wait(&sem3);
cout<<"5n";
sem_post(&sem1);
}
}
int main()
{
pthread_t t1;
pthread_t t2;
pthread_t t3;

sem_init(&sem1,0,1);
sem_init(&sem2,0,0);
sem_init(&sem3,0,0);
pthread_create(&t1,NULL,&fun1,NULL);
pthread_create(&t2,NULL,&fun2,NULL);
pthread_create(&t3,NULL,&fun3,NULL); 
pthread_join(t1,NULL);
pthread_join(t2,NULL);
pthread_join(t3,NULL);
sem_destroy(&sem1);
sem_destroy(&sem2);
sem_destroy(&sem3);
return 1;
}