信号量的问题
Issues with Semaphores
我正在尝试理解信号量,并且无法通过给定的约束来解决我的实现问题。我正在使用 6 个具有约束的线程:0,1,2 尽快完成工作;3 必须等待 0 和 1;4 必须等待 1 和 2 才能开始;5 应等待 0 和 2。我决定对这个特定问题使用 switch 语句,但似乎无法理解我哪里出错了。
#include <iostream>
#include <sched.h>
#include <time.h>
#include <pthread.h>
#include "sem.h"
#include <cstdlib>
#define THREAD_COUNT 6
using namespace std;
extern sim_semaphore create_sim_sem(int) ;
extern void wait_sem (sim_semaphore) ;
extern void signal_sem (sim_semaphore) ;
pthread_mutex_t stdoutLock ;
int thrds_finished ;
// global sync variables
sim_semaphore support_ready[THREAD_COUNT] ;
sim_semaphore finished ;
/* These are global variable to represent threads created
dynamically. */
pthread_t thr[THREAD_COUNT] ;
/* This is included to facilitate adding random delays in the code
-- as a debugging aid. */
extern long random(void);
int checking = 0 ;
/* A data type - a struct (class) with an int field to represent
a thread ID. */
struct threadIdType
{
int id ;
};
void init()
{
if ( 0!=pthread_mutex_init(&stdoutLock, NULL) )
{ cout << "MUTEX INITIALIZATION FAILURE!" << endl ;
exit(-1) ;}
thrds_finished = 0 ;
finished = create_sim_sem(0) ;
int count ;
for (count = 0; count < THREAD_COUNT ; count++)
{
support_ready[count] = create_sim_sem(0) ;
}
/* This initializes a random number generator */
srandom(time((time_t *) 0));
}
void rand_delay(int max)
{
int m_delay, j ;
m_delay = (int) random()%max ;
for (j=0; j<m_delay; j++) sched_yield();
}
void childMessage (int ID)
{
pthread_mutex_lock(&stdoutLock) ;
cout << "Child # " << ID
<< " has completed its assignment.n" ;
pthread_mutex_unlock(&stdoutLock) ;
}
void * child(void * idPtr)
{
int me = ((threadIdType *) (idPtr))->id, temp ;
rand_delay(100) ;
// wait constraints
switch(me)
{
case 0: break ; // thread 0 just 'goes'
case 1: break ; // thread 1 just 'goes'
case 2: break ; // thread 2 just 'goes'
case 3: wait_sem (support_ready[0]) ;
wait_sem (support_ready[1]) ; // thread 3 waits for both 0 and 1
break ;
case 4: wait_sem (support_ready[1]) ;
wait_sem (support_ready[2]) ; // thread 4 waits for both 1 and 2
break ;
case 5: wait_sem (support_ready[0]) ;
wait_sem (support_ready[2]) ; // thread 5 waits for both 0 and 2
break ;
default: pthread_mutex_lock(&stdoutLock) ;
cout << "nnBAD VALUE TO CASE STATMENT!!nn" ;
pthread_mutex_unlock(&stdoutLock) ;
exit (-1); break ;
}
rand_delay(1000) ;
/* Next increment thrds_finished - to keep track
of how many child processes have finished their
tasks. */
/* Here put code you may need for protecting
thrds_finished. */
/* HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH */
/* HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH */
/* This code increments thrds_finished in a way
that magnifies the problem if the critical section
problem is not solved correctly. Of course,
do not change this part of the code. */
temp = thrds_finished ;
rand_delay(1000) ;
temp++ ;
rand_delay(1000) ;
thrds_finished = temp ;
/* Here put additional code you may need for protecting
thrds_finished. */
/* HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH */
/* HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH */
/* Announce completion of the assignment. */
childMessage(me) ;
switch(me)
{
case 0: signal_sem(support_ready[0]);
signal_sem(support_ready[0]); // thread 0 signals for threads 3 5
break ;
case 1: signal_sem(support_ready[1]) ; // thread 1 signals for 3 4
signal_sem(support_ready[1]) ;
break ;
case 2: signal_sem(support_ready[2]) ; // thread 2 signals for 4 5
signal_sem(support_ready[2]) ;
break;
case 3: break;
case 4: break;
case 5: signal_sem (finished); break; // thread 5 signals to the mother
default: pthread_mutex_lock(&stdoutLock) ;
cout << "nnBAD VALUE TO CASE STATMENT!!nn" ;
pthread_mutex_unlock(&stdoutLock) ;
exit (-1); break ;
}
pthread_exit ((void *)0) ;
}
// spawn child threads and waits for them to finish
void mother()
{
int i;
threadIdType * idPtr ;
/* Create child threads numbered 1 through 8. */
pthread_mutex_lock(&stdoutLock) ;
cout << "Mother Begins Spawning Threads.n" << endl ;
pthread_mutex_unlock(&stdoutLock) ;
for (i = 0; i < THREAD_COUNT ; i++)
{
idPtr = new threadIdType ; /* allocate memory for struct */
idPtr->id = i ; /* records current index as the child's ID */
if ( 0!=pthread_create(&thr[i], NULL, child, (void *) idPtr) )
{ pthread_mutex_lock(&stdoutLock) ; /* 'error out' code here */
cout << "THREAD CREATION FAILURE!" << endl ;
pthread_mutex_unlock(&stdoutLock) ;
exit(-1) ; }
if (0!=pthread_detach(thr[i]))
{ pthread_mutex_lock(&stdoutLock) ;/* 'error out' code here */
cout << "THREAD DETACHMENT FAILURE!" << endl ;
pthread_mutex_unlock(&stdoutLock) ;
exit(-1) ;}
}
rand_delay(3000) ; /* Simulate whatever may delay the mother thread */
pthread_mutex_lock(&stdoutLock) ;
cout << "Mother Finishes Spawning Threads.n" << endl ;
pthread_mutex_unlock(&stdoutLock) ;
/* Some synchronization code is needed here to make the mother
behave correctly - she is not supposed to exit until after
all the children have finished their tasks. */
wait_sem (finished) ;
pthread_mutex_lock(&stdoutLock) ;
cout << "nAll children have now reported that they finished.n" ;
cout << "The value of the thrds_finished counter is: " ;
cout << thrds_finished << ".n" ;
if (thrds_finished != THREAD_COUNT)
cout << "BAD COUNTER VALUE!! - Critical Section Problem Failure!!n" ;
cout << "Mother exiting ... nn" ;
pthread_mutex_unlock(&stdoutLock) ;
return ;
}
int main()
{
cout << "nWelcome to The Child Thread Workplace!nn" ;
/* This calls the function that performs initializations. */
init();
/* Execute the mother() function */
mother();
return 0 ;
}
此线程应向生成子线程并等待它们完成的母函数发送信号。
我在这里的问题是,当我编译和运行时,有时并非所有线程都显示为已完成,并且似乎与给定的约束不同步。
您尚未发布足够的代码,以便我们能够完全诊断出问题所在(例如,您发布的内容中没有任何内容表明您如何确定线程已完成或未完成)。 但是从您所做的帖子来看,似乎至少有一部分问题可能是线程 5 只等待来自 0 和 2 的信号,然后发出"完成"的信号,而不管其他线程是否已经获得了他们的信号,更不用说完成了他们的工作了。
例如,线程 0、2 和 5 可以在线程 1、3 或 4 完全不运行的情况下完成其工作。
相关文章:
- C++ ABI 兼容性问题/张量流
- 删除旧的信号量系统V
- 父进程和子进程之间的 POSIX 信号量
- 访问共享内存而不使用易失性、std::atomic、信号量、互斥锁和自旋锁
- 多线程.如果我使用信号量,我可以在开始时创建很多线程还是应该只有几个线程?
- C/C++ - 用于按顺序打印数字的 sem_t 类型的单个信号量
- 单车道桥 使用信号量进行同步
- 用于 64 位/32 位 IPC 的 POSIX 信号量的替代方案?
- 这个餐饮哲学家问题(dpp)的解决方案是如何工作的?互斥体和信号量
- 发布信号量返回错误 6(无效句柄)
- 在 C Linux 中使用三个线程使用信号量同步按顺序打印 3 4 5 50 次
- 在使用 pthread 和信号量实现生产者-消费者问题时需要帮助
- 如何让一个线程继续,而另一个线程正在等待C++中的信号量
- 实现信号量
- 计算信号量还是互斥体?
- POSIX 信号量在高争用/负载下不起作用
- C++:提升:托管共享内存是否需要信号量锁
- 信号量的问题
- 信号量(互斥)问题
- perror()调用影响信号量锁定/解锁的问题