# Deadlockproblem

**URL:** <https://www.ruby-forum.com/t/deadlockproblem/97679>\
**Category:** Ruby\
**Created:** [July 9, 2006, 3:08pm UTC](https://www.ruby-forum.com/t/deadlockproblem/97679 "2006-07-09T15:08:54Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![asterix](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/839c29/32.png) [@asterix](https://www.ruby-forum.com/u/asterix)\
**Post date:** [July 9, 2006, 3:08pm UTC](https://www.ruby-forum.com/t/deadlockproblem/97679/1 "2006-07-09T15:08:54Z")

</div>

Hello,

i’m trying to realize asynchronous communication, but the sender have to  
wait until the answer is recieved.  
Although it is only one kind of message allowed at each time. Here is my  
code and the output.

using ruby-1.8.5 on winxp

* * *

require ‘thread’

$msgQueueGlobal = Queue.new  
$recieverList = Array.new

# 

# simulating the communication hardware

def sendMsgGlobal(msg)  
$msgQueueGlobal.push(msg)  
end

def recvMsgGlobal  
$msgQueueGlobal.pop  
end

recvThread = Thread.new {  
puts “start recvThread …”  
loop do  
msg = recvMsgGlobal()  
$recieverList[msg[0]].handleRecv(msg)  
end  
}  
puts “recvThread started”

# 

# Object holding sendMessagefunction wich have to be executed only once

a

# time

class Card  
def initialize(number)  
@nr = number  
$recieverList[@nr] = self

```
  @waitLock = false
  @waitMutex = Mutex.new
  @waitConditional = ConditionVariable.new

  @syncMutex = Mutex.new
  @syncConditional = ConditionVariable.new

```

end

def sendMsg  
@syncMutex.synchronize {  
msg = [@nr, " Message: #{Thread.current[:name]}"]  
puts “#{Thread.current[:name]}) sending message … \<#{msg}\>”

```
     @waitMutex.synchronize {
        @waitConditional.wait(@waitMutex) if @waitQueue
        @waitLock = true
     }

     sendMsgGlobal(msg)

     puts "#{Thread.current[:name]}) message send and waiting for 

```

answer …"  
@syncConditional.wait(@syncMutex)  
puts “#{Thread.current[:name]}) answer recieved \<#{msg}\>”  
}  
end

def handleRecv(msg)  
@syncMutex.synchronize {  
@syncConditional.signal  
}  
@waitMutex.synchronize {  
@waitLock = false  
@waitConditional.signal  
}  
end  
end

Thread.current[:name] = “Main”  
a = Card.new(0)

t1 = Thread.new { Thread.current[:name] = “t1”; a.sendMsg }  
t2 = Thread.new { Thread.current[:name] = “t2”; a.sendMsg }  
t3 = Thread.new { Thread.current[:name] = “t3”; a.sendMsg }  
t4 = Thread.new { Thread.current[:name] = “t4”; a.sendMsg }  
t5 = Thread.new { Thread.current[:name] = “t5”; a.sendMsg }  
t6 = Thread.new { Thread.current[:name] = “t6”; a.sendMsg }  
t7 = Thread.new { Thread.current[:name] = “t7”; a.sendMsg }  
t8 = Thread.new { Thread.current[:name] = “t8”; a.sendMsg }  
t9 = Thread.new { Thread.current[:name] = “t9”; a.sendMsg }

Thread.list.each{ |t| t.join if t }

* * *

output:  
start recvThread …  
recvThread started  
t1) sending message … \<0 Message: t1\>  
t1) message send and waiting for answer …  
t4) sending message … \<0 Message: t4\>  
t4) message send and waiting for answer …  
t3) sending message … \<0 Message: t3\>  
t3) message send and waiting for answer …  
t2) sending message … \<0 Message: t2\>  
t2) message send and waiting for answer …  
t1) answer recieved \<0 Message: t1\>  
t5) sending message … \<0 Message: t5\>  
t5) message send and waiting for answer …  
t8) sending message … \<0 Message: t8\>  
t8) message send and waiting for answer …  
t7) sending message … \<0 Message: t7\>  
t7) message send and waiting for answer …  
t6) sending message … \<0 Message: t6\>  
t6) message send and waiting for answer …  
t4) answer recieved \<0 Message: t4\>  
t9) sending message … \<0 Message: t9\>  
t9) message send and waiting for answer …  
t3) answer recieved \<0 Message: t3\>  
t2) answer recieved \<0 Message: t2\>  
t5) answer recieved \<0 Message: t5\>  
t8) answer recieved \<0  
deadlock 0x277c804: sleep:J(0x2817bd8) (main) -  
D:/\_studium/diplom/adios/AdiosTester.rb:79  
deadlock 0x2817bd8: sleep:- - C:/ruby\_1.8.5/lib/ruby/1.8/thread.rb:318  
C:/ruby\_1.8.5/lib/ruby/1.8/thread.rb:318: Thread(0x2817bd8): deadlock  
(fatal)  
from D:/\_studium/diplom/adios/AdiosTester.rb:79  
Message: t8\>  
t7) answer recieved \<0 Message: t7\>  
t6) answer recieved \<0 Message: t6\>  
t9) answer recieved \<0 Message: t9\>

* * *

My questions:

- why did this deadlock occur, and how can it be fixed
- is there another/better way for reaching this goal

with regards  
Asterix

---

<div class="post-metadata">

**Author:** ![asterix](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/839c29/32.png) [@asterix](https://www.ruby-forum.com/u/asterix)\
**Post date:** [July 9, 2006, 5:16pm UTC](https://www.ruby-forum.com/t/deadlockproblem/97679/2 "2006-07-09T17:16:59Z")

</div>

On Sun, 9 Jul 2006, Asterix Gallier wrote:

> Hello,
> 
> i’m trying to realize asynchronous communication, but the sender have to  
> wait until the answer is recieved.

but that’s synchronous! 😉

seriously, if the send always waits for the answer what good does it do  
thread  
your program?

> My questions:
> 
> - why did this deadlock occur, and how can it be fixed

among other things, you never do anything with @waitQueue - you simply  
always  
set @waitLock to true.

> - is there another/better way for reaching this goal

harp:~ \> cat a.rb  
require ‘thread’  
class Oracle  
def initialize  
@questions = Queue.new  
@thread = Thread.new(@questions){|q|  
loop{  
question, answer\_with = q.pop  
answer\_with[question.to\_s + ’ 42’]  
}  
}  
end  
def ask question, &answer\_with  
if answer\_with  
@questions.push [question, answer\_with]  
else  
q = Queue.new  
ask(question){|answer| q.push answer}  
Thread.new{ q.pop }  
end  
end  
def self.instance(\*a, &b) @instance ||= new(\*a, &b) end  
def self.ask(\*a, &b) instance.ask \*a, &b end  
end

# 

# you can block up front

# 

```
 n = -1
 p Oracle.ask("something #{ n += 1 }:").value

```

# 

# or ask and reap later

# 

```
 threads = []
 7.times{ threads << Oracle.ask("something #{ n += 1 }:") }
 threads.map{|t| p t.value}

```

harp:~ \> ruby a.rb  
“something 0: 42”  
“something 1: 42”  
“something 2: 42”  
“something 3: 42”  
“something 4: 42”  
“something 5: 42”  
“something 6: 42”  
“something 7: 42”

regards.

-a

---

<div class="post-metadata">

**Author:** ![asterix](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/839c29/32.png) [@asterix](https://www.ruby-forum.com/u/asterix)\
**Post date:** [July 9, 2006, 6:47pm UTC](https://www.ruby-forum.com/t/deadlockproblem/97679/3 "2006-07-09T18:47:30Z")

</div>

Thank you very much for your answer, i will try to solve my problem  
based on the code you gave me.

Cheers  
Asterixh
