您好我正在进行有关使用具有多信号量的POSIX线程的任务。分配的简要说明是:有4种不同的数据包(字符/视频/音频/图像),每个数据包由不同的线程承载,我们也有共享缓冲区。最大线程可以在系统上工作,将由用户作为输入维护。例如;如果用户输入10,则可以创建最多10个线程,以在给定时间内通过缓冲区传输数据包。现在令我困惑的部分是,这个缓冲区可以立即包含有限的数据包。 (例如,它可以包含最多10个char数据包和20个视频数据包等),因此我们必须为每种数据类型提供不同的信号量。问题我知道如何用信号量控制缓冲区大小这很简单,但不能设置使用数据包信号量的正确想法。即使我尝试了一些不同的方法,我总是遇到死锁错误。这是我的伪代码,可以更清楚地了解我的程序。
define struct packege
define semaphore list
main
initialize variables and semaphores
while threadCounter is less than MaxThreadNumber
switch(random)
case 0: create a character package
create a thread to insert the package in buffer
case 1: create a video package
create a thread to insert the package in buffer
case 2: create an image package
create a thread to insert the package in buffer
case 3: create an audio package
create a thread to insert the package in buffer
increment threadCounter by one
end of while
create only one thread which will make the dequeue operation
end of main
producer function
for i->0 to size_of_package
sem_wait(empty_buffer) // decrement empty_buffer semaphore by size of package
lock_mutex
insert item into queueu
decrement counter of the buffer by size of package
unlock_mutex
for i->0 to size_of_package
sem_post(full_buffer) // increment full_buffer semaphore by size of package
end of producer function
consumer function
while TRUE // Loops forever
lock_mutex
if queue is not empty
dequeue
increment counter of the buffer size of package
unlock_mutex
for i->0 to size_of_package // The reason why i making the sem_wait operation here is i cant make the dequeue in outer region of mutex.
sem_wait(full_buffer)
for i->0 to size_of_package
sem_post(empty_buffer)
end of consumer function
使用此实现程序正常工作。但我不能正确使用信号量,它属于包的线程。我可以倾听每一个建议,并会对每个答案表示赞赏。
答案 0 :(得分:1)
这不是信号量的使用方式。缓冲区的控制变量/结构应该计算缓冲区中包含的消息数量以及类型。互斥锁保护缓冲区及其控制变量/结构免受不同线程的并发访问。信号量(如果使用的话)只是向缓冲区发送缓冲区的状态信号,并且与数据包的大小没有关联;它肯定不会增加数据包的大小!
建议您使用pthread条件变量而不是信号量。它们与pthread互斥锁一起使用,以保证线程之间的无竞争信令。生产者循环执行此操作:
消费者循环执行此操作:
阅读pthread_cond_init
,pthread_cond_signal
和pthread_cond_wait
。
答案 1 :(得分:1)
由于它是一个赋值,你可能不需要读取和写入真正的数据包数据,而只是模拟它们的处理。
在这种情况下,问题归结为如何在生产者线程达到可以在缓冲区中写入的数据包限制时有效地阻止生产者线程。目前,据我所知,您正在使用信号量来计算缓冲区中写入的数据包的各个元素。
想象一下,您在缓冲区中的写入是原子的,并且您只想计算数据包,而不是数据包元素。每次生产者写入数据包时,它必须使用适当的信号量向消费者发送信号,并且每次消费者读取数据包时,它必须将信号发送给适当的生产者。
让我强调其他几点:
正如我所说,制作人必须发信号通知它写了一个数据包,但一旦达到阈值就必须停止。为实现这一目标,您可以在每次发布新数据包时使用sem_get
获取信号量。每次读取数据包时,消费者都会执行sem_post
,这与您使用单个信号量版本所做的相反。但是,由于您希望生产者停在阈值处,因此初始化信号量的容量为N - 1
,N为阈值。请注意,在缓冲区中写入新数据包后,必须发出新数据包的信号,否则消费者可能会阻止缓冲区。
producer<type> function
write_packet() // put the packet in the buffer
sem_wait(type) // signal a new packet is available
// (if there's not enough space for another packet, the producer will block here)
end producer<type> function
consumer function
while TRUE // Loops forever
switch packet_available() // look if there's a new packet available
case video:
read_packet<video>()
sem_post(video)
(...)
default: // no packet available, just wait a little
sleep()
end if
end while
您仍需要定义packet_read
,packet_write
和packet_available
函数,可能使用互斥锁来限制对缓冲区的访问。