<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">Hi,<br>
      <br>
      No, it's not a bug. It's a race in the calling code. The spawned
      process sends the first io-request and the shell sends the second.
      The first "read" will be overridden while the shell's request is
      served. They are so to say stacked. Having two processes (the
      shell and your newly spawned process) reading from the same
      io-device is generally not a good idea, they are competing for a
      single resource that is kind of hard to share... You have to keep
      other processes from tampering with your terminal while you're
      reading it, in this case by letting the shell wait for your
      process.  <br>
      <br>
      In fact, you actually get your prompt from the spawned process
      written, but the shell will override/overwrite it. Try sleeping
      the shell for a second and your prompt will temporarily be shown,
      but then the shell comes back and your prompt disappears again. If
      you sleep for a while in the child process before reading, the
      child will instead override the shell. There's no telling which
      one will be stacked upon the other. It's kind of impossible to
      determine which order is preferred by the caller... So, your
      program has to decide on the order by synchronizing it's
      activities.<br>
      <br>
      Example:<br>
      1> Prompt = "Please enter data: ".<br>
      2> F = fun() -> try Result = io:read(Prompt),
      io:format("Res: ~p~n",[Result]) catch A:B -> io:format("Read
      error: ~p:~p~n",[A,B]) end end.<br>
      3> {Pid,Ref} = spawn_monitor(F), receive after 1000 -> ok
      end.<br>
      %% "Please Enter data: " will be shown for a second, then
      disappears and the shell prompt comes back.<br>
      4> receive after 1000 -> ok end.<br>
      %% Please enter data will appear again, but disappears after a
      second again.<br>
      5> receive {'DOWN',Ref,process,Pid,_} -> ok end.<br>
      Please enter data: hi.<br>
      Res: {ok,hi}<br>
      %% Now try waiting a second to make the shell send the io-request
      before your spawned process<br>
      6> G = fun() -> try receive after 1000 -> ok end, Result
      = io:read(Prompt), io:format("Res: ~p~n",[Result]) catch A:B ->
      io:format("Read error: ~p:~p~n",[A,B]) end end. <br>
      7> spawn(G).<br>
      %% First you will see the shell prompt for ~ a second, then you
      will get:<br>
      Please enter data: hello.<br>
      Res: {ok,hello}<br>
      8> <br>
      <br>
      In other words, do not have two processes competing tor one
      terminal, it will only give confusing results :)<br>
      <br>
      Cheers,<br>
      /Patrik, OTP<br>
      <br>
      On 11/30/2012 01:57 PM, Álvaro wrote:<br>
    </div>
    <blockquote
cite="mid:CAMzC0oY8Rjqf_rYnz+JNeA_UBhGPUpjMDKOOBZSv=SHZzH_xEA@mail.gmail.com"
      type="cite">
      <meta http-equiv="Content-Type" content="text/html;
        charset=ISO-8859-1">
      Dear all,<br>
      <br>
      Every time I run this simple code, my program gets stuck:<br>
      <br>
      > Pid = spawn (moduleName,myread,["hello"]).<br>
      <br>
      where:<br>
      <br>
      myread(Prompt)-><br>
          try<br>
            Result = io:read(Prompt),<br>
            io:format("Res: ~p~n",[Result]),<br>
          catch<br>
          A:B-><br>
              io:format("Read error: ~p:~p~n",[A,B]),<br>
              false<br>
          end.<br>
      <br>
      <br>
      if I check the status of the process:<br>
      <br>
      > erlang:process_info(Pid).<br>
      <br>
      [{current_function,{io,wait_io_mon_reply,2}},<br>
       {initial_call,{default_environment,myread,1}},<br>
       {status,waiting},<br>
       {message_queue_len,0},<br>
       {messages,[]},<br>
       {links,[]},<br>
       {dictionary,[]},<br>
       {trap_exit,false},<br>
       {error_handler,error_handler},<br>
       {priority,normal},<br>
       {group_leader,<0.25.0>},<br>
       {total_heap_size,233},<br>
       {heap_size,233},<br>
       {stack_size,7},<br>
       {reductions,28},<br>
       {garbage_collection,[{min_bin_vheap_size,46368},<br>
                            {min_heap_size,233},<br>
                            {fullsweep_after,65535},<br>
                            {minor_gcs,0}]},<br>
       {suspending,[]}]<br>
      <br>
      <br>
      It seems to be stuck in the function io:wait_io_mon_reply/2
      (surfing through io.erl I found that this function waits for a
      response from the  process managing the io ). This process is not
      answering, hence my code stops working.<br>
      I've checked that the "group_leader()" once I spawn the reading
      process is the same used by my shell.<br>
      <br>
      Any ideas on how to deal with it?<br>
      <br>
      Regards,<br>
      Álvaro<br>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <br>
      <pre wrap="">_______________________________________________
erlang-questions mailing list
<a class="moz-txt-link-abbreviated" href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a>
<a class="moz-txt-link-freetext" href="http://erlang.org/mailman/listinfo/erlang-questions">http://erlang.org/mailman/listinfo/erlang-questions</a>
</pre>
    </blockquote>
    <br>
  </body>
</html>