mIRC Home    About    Download    Register    News    Help

Print Thread
Simple Threads (beating a dead horse) #196607 20/03/08 05:27 AM
Joined: Jul 2006
Posts: 12
S
SartenX Offline OP
Pikka bird
OP Offline
Pikka bird
S
Joined: Jul 2006
Posts: 12
Yes, I know there's 2 other discussions on this. One of them missed the point and the other quickly went into a philosophical rant about whether there's an implicit improvement in multithreading (Frankly, RRX's post on the last page was the first to have useful content).

My very simple solution: A new command, (/thread [command]) that causes a command (or alias) to run in a new thread and the original thread continues immediately (or as close to immediately as possible). Such behavior, minus the actual threading, could be simulated with:

Code:
alias thread {
  .timer 1 0 $1-
}


That's it. Variables may or may not match for each thread (whatever's easiest for Khaled). Sharing hash tables and other global resources would be useful, but still not required.

In other words, it'd be like threads in other languages: If you want locking, you can code it yourself. Same thing for semaphores, dispatching, and every other management function. I have no doubt that Khaled COULD add easy pre-built systems for such features, but I see little need.

Simple sleeping can be done with just waiting for a variable to change, and another thread changes that variable. If variables aren't shared, a file could be used in place of a variable.

Threads don't inherently need complex management. MIRC's language is powerful enough that if a given application needs such management, a competent scripter could add it without much trouble.

Now, most of my experience with parallel processing comes from Java, but I see no reason why this simple solution wouldn't work.

-Sarten-X

Re: Simple Threads (beating a dead horse) [Re: SartenX] #196608 20/03/08 06:36 AM
Joined: Oct 2003
Posts: 3,918
A
argv0 Offline
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
I'm sure this has been mentioned in either of the posts you referenced (but did not link to), but mIRC is not thread-safe, meaning the solution is not simple at all.

As much as you may think just creating a new thread and letting the scripter deal with thread safety will be a good solution, that will never work. Your assumption is that K can just create a new thread and that existing mIRC commands will continue to work fine in the new threads-- but they won't. Even simple things such as /echo probably has a nifty race condition somewhere. A scripter cannot manage his own thread data if the very commands the scripter uses have their own threading bugs.

Most of the data relevant to scripting is statically allocated in mIRC's data space (event info, data read from the socket, current connection id)-- meaning it would be like trying to multithread a singleton class in Java, if you need an analogy. For instance, lets assume for argument sake that mIRC stores the active cid in some global variable called "int active_cid". If I spawn two threads performing a /scid command on respective connection ids, there is an obvious race condition there, and there is nothing the scripter can do to stop it.

This is the design mIRC has (unfortunately?) chosen. It is not threading aware. The entire language would need to be rewritten with threading in mind-- and that is highly unlikely to ever happen (in the near future) given the enormous amount of work that requires...

I would suggest stop beating a dead horse and just deal with mIRC as mIRC is. There is nothing wrong with event oriented programming. Not only is it the way things are done in the Windows API, but Tcl already uses such a design (http://wiki.tcl.tk/1772) and does so successfully. I think this issue really comes down to a lack of understanding of the power of event-loops. They're far safer, far easier to use, and when performance is not an issue (it definitely is not in mIRC script) are a much better design choice. Java may have a great threading model, and Haskell may have amazing Monads-- but this is mIRC. In mIRC, "threads" are /timers as you very well pointed out-- there's no need for the "actual threading" part.


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
Re: Simple Threads (beating a dead horse) [Re: SartenX] #196610 20/03/08 09:14 AM
Joined: Apr 2004
Posts: 759
M
Mpdreamz Offline
Hoopy frood
Offline
Hoopy frood
M
Joined: Apr 2004
Posts: 759
You could use this dll to achieve what you're aiming for.


$maybe
Re: Simple Threads (beating a dead horse) [Re: SartenX] #196616 20/03/08 03:52 PM
Joined: Jul 2006
Posts: 12
S
SartenX Offline OP
Pikka bird
OP Offline
Pikka bird
S
Joined: Jul 2006
Posts: 12
argv0: This is essentially the same argument you brought up that lead to the philosophical discussion in the other thread. The only purpose it serves is to propagate further misunderstanding. It is ABSOLUTELY possible to implement thread safety in unsafe environments, with the proper application of locks. It is not the language's job to provide a perfect environment for threads.

Having threaded a 2K-line singleton class (a filesystem, of sorts), I can safely say it's fairly simple. All the access to the data was simply made atomic, so there could be no conflict without explicitly creating one.

MIRC race conditions can be solved in a similar fashion. To use your example of the active cid, and in fact anything else, a scripter could simply create a unique hash table containing all the variables they need. The thread could then access that hash table without worrying about race conditions.

Output commands would be simple as well. Just run them in whatever the active context is. Yes, this means some commands will run on different connections than they started. Aw shucks.

For more capabilities, feel free to design your own solution, such as sending a signal back to the main thread, which won't have access issues. That is one of the most enjoyable parts of programming: given a simple environment, construct the tools you need.

Moving on: Performance is indeed an issue in mIRC. Consider the number of scripts that focus on visual presentation. Should those scripts be forced to cripple the client itself for the sake of drawing a shiny picwin? Or should they be limited in artistic ability to preserve the client's functioning? Why should the designer even have to choose?

On another note, there are some algorithms that just don't lend themselves well to event oriented programming. There's no question that they CAN be converted, but it's not easy, and rarely optimal.

In conclusion, I see this as just another tool. If implemented, I can imaging seeing threaded displays on picwins, faster responses on large scripts, greatly improved data processing abilities, and an overall increase in the possibilities mIRC script provides.

MPDreamz: Thank you for your useful solution. A cursory glance at the code appears to do exactly what I'd like. I'm not sure about the details of its use, but it looks good.

However, in my opinion, DLLs are still not an ideal solution. This goes not just for threading, but most other applications as well. They are too large and unwieldy to easily distribute with a script, and in some cases face licensing issues.

Re: Simple Threads (beating a dead horse) [Re: SartenX] #196623 20/03/08 06:19 PM
Joined: Oct 2003
Posts: 3,918
A
argv0 Offline
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
If you think discussing thread-safety is "philosophical" than you're sorely mistaken.

Quote:

It is ABSOLUTELY possible to implement thread safety in unsafe environments


It is, but only when the methods you use to implement thread-safety are in themselves thread-safe-- the same way you can't build a sturdy house on a foundation of mud. Nothing you can use in mIRC will be thread safe, as mIRC shares everything. You seem to be suggesting "just wrap every command in a lock and you'll be fine".. you won't end up with any threading at all, just one big lock wrapping every single command leading to an effectively single threaded system.

Quote:

MIRC race conditions can be solved in a similar fashion. To use your example of the active cid, and in fact anything else, a scripter could simply create a unique hash table containing all the variables they need. The thread could then access that hash table without worrying about race conditions.


This is assuming that the "simple" act of creating the unique hash table will not have any race conditions.. does it? I don't know. Does that mean using /hadd will avoid any threading issues? Probably not.

Quote:

Output commands would be simple as well. Just run them in whatever the active context is.


Again, assuming the output commands are themselves thread-safe, which is not guaranteed.

Your performance claim is bogus. Threading will not solve much of mIRC's problems with speed. Again, look no further than Windows itself, which performs very well in terms of windowing vs picwins and does so in a completely single threaded environment using event loops. Why is it fast? Because the core codebase is fast. Threading would not make it that much more efficient than it is. If you really need performance, use DLLs.

Quote:

That is one of the most enjoyable parts of programming: given a simple environment, construct the tools you need.


Again, mIRC gives you dlls. One of the most simplistic environments. Feel free to construct all the low-level threading tools you need using that if you truly understand how to solve the problem. Having K Implement a half-assed threading model in which the scripter is responsible for all context control would be more detrimental than helpful to the average scripter. If you believe yourself to be more advanced than the average, well, DLLs should be no problem to you, then. By the same token, if you can't handle DLLs, you probably can't handle what is involved in proper threading, either.

PS.
There are no licensing issues with DLLs-- no more licensing issues than with a plaintext script file. Any licensing you choose to use on *your code* is your decision. This would work the same way for any .mrc, .ini, .txt, .bmp file you distribute, ever. DLLs are also no more large than unwieldly script files. Those are, again, completely bogus claims.



- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
Re: Simple Threads (beating a dead horse) [Re: argv0] #196640 20/03/08 11:48 PM
Joined: Jul 2006
Posts: 12
S
SartenX Offline OP
Pikka bird
OP Offline
Pikka bird
S
Joined: Jul 2006
Posts: 12
Thank you for illustrating a complete lack of understanding of several topics. I've given my points, and we'll see how it goes.

Re: Simple Threads (beating a dead horse) [Re: SartenX] #197001 27/03/08 03:13 AM
Joined: Jan 2003
Posts: 22
M
myndzi Offline
Ameglian cow
Offline
Ameglian cow
M
Joined: Jan 2003
Posts: 22
lolololol








....yes, that's all I have to say.

Re: Simple Threads (beating a dead horse) [Re: SartenX] #197095 28/03/08 07:03 PM
Joined: Jan 2004
Posts: 509
L
LostShadow Offline
Fjord artisan
Offline
Fjord artisan
L
Joined: Jan 2004
Posts: 509
Unfortunately, 1 of the things we learn in a rational debate is that we can't ignore the other user's arguments. You agree with everything the argument says except when you find errors in it. Simply saying "I disagree" without pointing out the errors or flaws in other other people's arguments is not a valid counter-argument.

Originally Posted By: SartenX
Thank you for illustrating a complete lack of understanding of several topics.

That's very easy to say that. Much harder to show why.

Quote:
I've given my points, and we'll see how it goes.

And you gave up.

-Neal (Neal from Webnet, ltns).