1. Phix: Understanding Multithreading

Hey, Pete! Can you fix this simple demo for me? I'm just trying to get a better grip on multithreading.

It actually works for a few seconds, doing what it's supposed to do, but then it crashes.

I think I got it! I was using a plain ?x, and I think maybe that's what was crashing it.

If you run the below code without the enter_cs()/leave_cs(), it crashes eventually. With them there, it works.

Pete, let me know if I'm on the right track here!

Thank you!

-- simple app to show multi-threading in Phix 
-- start 4 threads 
-- each thread will wait X seconds and then print its output 
 
atom cs = init_cs() 
bool terminate = false 
 
constant ESC = #1B 
 
procedure counter(integer x) 
atom nowTime 
atom endTime = time() + x 
    while not terminate do 
        nowTime = time() 
        if nowTime >= endTime then 
            endTime = nowTime + x 
            enter_cs(cs) --<-- this is required to not crash 
            ?x 
            leave_cs(cs) --<-- this is required to not crash 
        end if 
    end while 
    exit_thread(0) 
end procedure 
atom rid = routine_id("counter") 
 
procedure main() 
sequence threads = { 
        create_thread(rid,{1}), 
        create_thread(rid,{2}), 
        create_thread(rid,{4}), 
        create_thread(rid,{8}) 
    } 
 
    while not find(get_key(),{ESC,'q','Q'}) do 
    end while 
    terminate = true 
    wait_thread(threads) 
    delete_cs(cs) 
 
    puts(1,"done") 
    if getc(0) then end if 
 
end procedure 
 
main() 
new topic     » topic index » view message » categorize

2. Re: Phix: Understanding Multithreading

When using multithreading, shared reference counts (especially the hidden ones on literal constants) are a real pita.

The problem you hit is builtins/VM/pprntfN.e, aka sprintf(), is not thread safe - I have just made the following (yet more) fixes to it:

--                  result = "1"&result 
                    result = '1'&result 
                else 
--                  result = "-1"&result[2..$] 
                    result = '-'&'1'&result[2..$] 
 
--          reve = "0" 
            reve = repeat('0',1) 
 
--                      if find(result,{"","-","+"}) then 
                        if length(result)=0 
                        or (length(result)=1 and (result[1]='-' or result[1]='+')) then 
 
--string hexchar 
string hexchar, dxoetc 
 
            hexchar = "0123456789ABCDEFabcdef" 
            dxoetc = "dxobscvefgEXG" 
 
--              fidx = find(fi,"dxobscvefgEXG") 
                fidx = 0 
                for dx=1 to length(dxoetc) do 
                    if fi=dxoetc[dx] then 
                        fidx = dx 
                        exit 
                    end if 
                end for 
 
--              or (showcommas and find(fi,"df")=0) then 
                or (showcommas and fi!='d' and fi!='f') then 

EDIT: oops, i ==> dx
As you say though, that enter_cs()/leave_cs() is a perfectly fine way to deal with it as well, and the above is for educational purposes only.

I suppose multithreading is a bit like working for MI6 or the NSA - you have to be really paranoid about privacy. Ideally you should do the absolute bare minimum work in the thread itself, and pass the results back to the main thread for any printing/logging/storing, etc.

new topic     » goto parent     » topic index » view message » categorize

3. Re: Phix: Understanding Multithreading

petelomax said...

Ideally you should do the absolute bare minimum work in the thread itself, and pass the results back to the main thread for any printing/logging/storing, etc.

Ah, like the loggit() functionality... Thanks for the help!

new topic     » goto parent     » topic index » view message » categorize

4. Re: Phix: Understanding Multithreading

petelomax said...

When using multithreading, shared reference counts (especially the hidden ones on literal constants) are a real pita.

The problem you hit is builtins/VM/pprntfN.e, aka sprintf(), is not thread safe - I have just made the following (yet more) fixes to it:

Does this mean '?' is now thread safe?

new topic     » goto parent     » topic index » view message » categorize

5. Re: Phix: Understanding Multithreading

euphoric said...

Does this mean '?' is now thread safe?

Maybe/maybe/no/no:

Maybe: I have already had five or six previous attempts at this...
Maybe: ? uses sprint() uses sprintf(), and I only changed the latter.
No: Mixing output from several threads on one screen will get very messy.
No: I will never claim it is nor recommend using ? from background threads[1].

PS: I should probably also say there is some merit for a thread-safe sprintf(), and even non-1 file i/o,
but I do not feel the same for the console (or gui), [1]at least that is without an explicit enter_cs()/leave_cs().

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu