Jump to content
  • Sky
  • Blueberry
  • Slate
  • Blackcurrant
  • Watermelon
  • Strawberry
  • Orange
  • Banana
  • Apple
  • Emerald
  • Chocolate
  • Charcoal
  • 0
standinonstilts

Multi Threaded Send and Receive

Question

I want to create a server that pulls the modem_message event and prints to the console, but I also want the computer to be able to send messages (based on io.read()) while waiting for a message. I tried using threads, but I think I am using them wrong. As far as I know there is no thread.sleep() so I'm not sure how to suspend a thread for a short period of time so that you can still type messages, but still have that thread automatically continue. How would I go about doing this?

Link to post
Share on other sites

3 answers to this question

Recommended Posts

  • 1

> I want to create a server that pulls the modem_message event and prints to the console

Cool, you can `listen` or `pull` for that event

> but I also want the computer to be able to send messages (based on io.read()) while waiting for a message.

`listen` works well for background handling, while in the foreground you are doing other work (such as io.read). However, you want your background to also print to the console? That'll obscure/interfere (visually) with the io.read getting user input. But okay

> I tried using threads

Sure, threads can do this job too. With threads, your event handling can be designed in a more selfish manner. You can `event.pull` and such without worrying about blocking the rest of the system

> but I think I am using them wrong.

Feel free to share some code!

> As far as I know there is no thread.sleep() so I'm not sure how to suspend a thread for a short period of time

No, there isn't. But, calling `os.sleep` from inside the thread is identical to what you would expect from `thread.sleep`. **HOWEVER** (please keep reading)

> so that you can still type messages, but still have that thread automatically continue. How would I go about doing this?

I wouldn't call `os.sleep` in THIS program because you want your thread to handle specific messages. `os.sleep` is a RUDE sleep, it DROPS events in the garbage. If any modem_messages occur during the sleep, you missed them. Instead, just pull with a timeout, `event.pull(.5, "modem_message")` in fact, I don't see the point of giving a timeout at all. Is your modem_message thread doing anything else or just waiting for modem_messages? Just call `event.pull("modem_message")` in your thread, done

local thread = require("thread")
local event = require("event")

local t = thread.create(function()
	while true do
		local pack = table.pack(event.pull("modem_message"))
		print(table.unpack(pack))
	end
end)

while true do
	local command = io.read()
	if command == "quit" then
		break
	end
end

t:kill()

 

BTW: os.sleep *does not* rob events from any other thread or process, it only throws away events of its own process

Link to post
Share on other sites
  • 1
5 hours ago, standinonstilts said:

 

local t1 = thread.create(handleMessage()) 

This is definitely not a bug in the thread library, but instead you misunderstand what this code is doing -- having nothing to do with threads, but in the logic of the code you have written

You are attempting to store the thread.create result in your local variable, t1 -- nothing wrong there

thread.create takes a single parameter, a FUNCTION. `handleMessage` is a function, but `handleMessage()` is the invocation of that function. Thus, you are attempting to pass the RESULT of `handleMessage` (i.e. the value returned by `handleMessage`) as the argument to `thread.create`. Thus, `handleMessage()` executes, and must complete and return a value before thread.create is called

What do you think this code would do?

local function a()
	return "foobar"
end

local function b(value)
	print(value)
end

b(a())

compared to if instead of calling `b(a())`, you were to call `b(a)`

 

To fix your code, you need to pass the function, not the result of the function:

local t1 = thread.create(handleMessage)

Your code is stuck executing handleMessage(), and never returns to thread.create

Link to post
Share on other sites
  • 0
18 hours ago, payonel said:

local thread = require("thread")
local event = require("event")

local t = thread.create(function()
	while true do
		local pack = table.pack(event.pull("modem_message"))
		print(table.unpack(pack))
	end
end)

while true do
	local command = io.read()
	if command == "quit" then
		break
	end
end

t:kill()

 

my code was very close to yours. the only difference was that instead of creating a function inside the thread.create(), I created a seperate function named handleMessage() and called it as: 

local t1 = thread.create(handleMessage()) 

whenever I do this, I cannot type input, it's like the thread is blocking the io.read; but when you define the function inside thread.create() it allows me to read and print perfectly fine. Is there a reason for this or is it a bug?

 

my code:

 

local event = require("event")
local thread = require("thread")
local modem = component.modem

modem.open(77)

function handleMessage()
  while true do
    local pack = table.pack(event.pull("modem_message"))
    print(table.unpack(pack))
  end
end

local t1 = thread.create(handleMessage()) 

while true do
  local command = io.read()
  print(command)
end

t1:kill()

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use and Privacy Policy.