[Mono-devel-list] Re: Mono-devel-list digest, Vol 1 #1576 - 3 msgs

Michael Rasmussen mir at miras.org
Sat Apr 2 22:49:01 EST 2005


lør, 02 04 2005 kl. 11:05 -0500, skrev Jonathan Pryor:

> It appears that this won't be possible, at least for now.  The primary
> reason is that Mono is multi-threaded by default -- a "Hello World"-
> style program has 3 threads active by default (I don't know what they're
> doing, but I'm seeing 3 process id's in /proc/PID/task under Linux, and
> IIRC each "task" is a thread).
> 
Strange, I only see one thread for my hello world?
Below is a small script using fork:
// project created on 21-03-2005 at 15:16
using System;
using System.Net.Sockets;
using System.IO;
using Mono.Posix;

namespace TCPSocketServer
{

	public class Server
	{
		private StreamWriter streamWriter;
		private StreamReader streamReader;
		
		public Server(int port)
		{
			System.Int32 pid, sid;
	
			pid = Syscall.fork();
			if (pid < 0) {
	    		Syscall.exit(1);
			}
			/* If we got a good PID, then
	   		   we can exit the parent process. */
			if (pid > 0) {
				Console.WriteLine("Parent: Signing off!");
				Console.WriteLine("Parent PID: " + pid);
	    		Syscall.exit(0);
			}
			/* Create a new SID for the child process */
			sid = Syscall.setsid();
			if (sid < 0) {
				Console.WriteLine("Could not get a pid for child");
	    		Syscall.exit(1);
			}
			Console.WriteLine("Client running as deamon with pid " + sid);
			CreateSocket(port);
			if (!StartServer()) {
				Console.WriteLine("Unable to start server");
				Syscall.exit(1);
			}
		}
		
		public static void Main(string[] args)
		{
			int port;
			
			if (args.Length > 0)
				port = Convert.ToInt32(args[0]);  
			else
				port = 1234;
			new Server(port);
		}

		private bool CreateSocket(int port)
		{
			TcpListener tcpListener = new TcpListener(port);
			tcpListener.Start();
			Console.WriteLine("Server started");
			Socket socket = tcpListener.AcceptSocket();
			
			try
			{
				if (socket.Connected) {
					Console.WriteLine("Client connected");
					NetworkStream networkStream = new NetworkStream(socket);
					streamWriter = new StreamWriter(networkStream);
					streamReader = new StreamReader(networkStream);
				}
			}
			catch (Exception e)
			{
				Console.WriteLine(e.StackTrace);
				return false;
			}
			return true;
		}
		
		private bool StartServer()
		{
			while (true) {
				string input = streamReader.ReadLine();
				Console.WriteLine("Client: " + input);
				streamWriter.WriteLine("Hi dude. You sent this:\n" + input);
				streamWriter.Flush();
			}
		}		
	}
}

loke:~/Projects/appserver/fork$ cat /proc/19900/task/19900/status
Name:   mono
State:  S (sleeping)
SleepAVG:       76%
Tgid:   19900
Pid:    19900
PPid:   1
TracerPid:      0
Uid:    1000    1000    1000    1000
Gid:    1000    1000    1000    1000
FDSize: 32
Groups: 25 1000
VmSize:    14152 kB
VmLck:         0 kB
VmRSS:      4788 kB
VmData:     3736 kB
VmStk:        16 kB
VmExe:      1360 kB
VmLib:      5756 kB
VmPTE:        24 kB
Threads:        1
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000000
SigCgt: 00000001a08004cc
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000

> Since it appears that TLS data isn't preserved after the fork(2) call,
> you can't do a P/Invoke call at all after a fork -- meaning I should
> remove fork and exec from Mono.Unix.Syscall, and replace the pair of
> them with a MS-DOS "spawn" equivalent (or just skip the whole thing and
> have people use System.Diagnostics.Process instead, which sounds better
> all the time...).
> 
How does it work on windows when you install an application running as a
service? What part of the winapi is used? (Sorry for asking this if it
is a trivial question. By knowledge of windows is very sparse)

> You could write a wrapper in sh(1), and avoid the C code. :-)
> 
That would not be particularly portable. The reason for hunting a
solution for this problem is that I am involved in a project which is to
create an application server that should be able to run both under
windows an linux. Under windows it is possible to have the server
installed as a service:

                public static void Install()
                {
                        ServiceInstaller si = new ServiceInstaller();
                        ServiceProcessInstaller spi = new
ServiceProcessInstaller();
                        spi.Account = ServiceAccount.LocalSystem;
                        si.Parent = spi;
                        si.DisplayName = DISPLAY_NAME;
                        si.ServiceName = SERVICE_NAME;
                        si.StartType = ServiceStartMode.Automatic;

                        si.Context = new
System.Configuration.Install.InstallContext("install.log", null);

                        string
asmpath=Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, AppDomain.CurrentDomain.FriendlyName);
                        si.Context.Parameters["assemblypath"] ="\"" +
asmpath +
"\" /s";

                        IDictionary stateSaver = new Hashtable();
                        si.Install(stateSaver);
                }

> This is especially attractive, as the mono convention is to provide a
> shell script to start your program (/usr/bin/mcs is a shell-script), so
> you could modify this shell script to run "nohup mono myprogram.exe" if
> your --background option is specified.
> 
This could be a working hack. Not entirely satisfactory though.

> As for portability, you've lost portability as soon as you use
> Mono.Unix, which (except for Stdlib and related classes) will only run
> under Unix-like platforms.  If you're on a Unix-like platform, you
> should be able to add your own P/Invoke calls relying upon unix
> functionality.
> 
I see your point.
> I think we also have differing opinions behind the "whole idea behind
> C#".  It is not a Java replacement, attempting to provide "write once,
> run anywhere" portability -- just looking at System.Windows.Forms should
> reinforce this.  Mono/C# is an environment allowing greater productivity
> while still making the most of your target platform.  If you can do this
> while being portability, so much the better, but Mono won't try to
> ensure portability.  The ease of P/Invoke should reinforce this view.
Bad formulated from me. What I meant to argue was the idea behind Mono
is to be able to have an application written on either *nix or windows
to be able to run on all platforms which is supported by mono or dot
net.

Hilsen/Regards
Michael Rasmussen

Get my public GnuPG keys:
michael  rasmussen  cc
http://keyserver.veridis.com:11371/pks/lookup?op=get&search=0xD3C9A00E
mir  datanom  net
http://keyserver.veridis.com:11371/pks/lookup?op=get&search=0xE501F51C
mir  miras  org
http://keyserver.veridis.com:11371/pks/lookup?op=get&search=0xE3E80917
--------------------------------------------------------------
Princess Leia:
I'll be back.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Dette er en digitalt underskrevet brevdel
Url : http://lists.ximian.com/pipermail/mono-devel-list/attachments/20050403/46329344/attachment.bin 


More information about the Mono-devel-list mailing list