performance problem with process fork in gcj compiled CNI

Ricardo Temporal ricardotemporal@hotmail.com
Fri Jan 27 14:25:00 GMT 2006


Hi,
 I saw SUSV3 about the fork and really pthread_atfork documentations says:
"There are at least two serious problems with the semantics of fork() in a 
multi-threaded program. One problem has to do with state (for example, 
memory) covered by mutexes. Consider the case where one thread has a mutex 
locked and the state covered by that mutex is inconsistent while another 
thread calls fork(). In the child, the mutex is in the locked state (locked 
by a nonexistent thread and thus can never be unlocked). Having the child 
simply reinitialize the mutex is unsatisfactory since this approach does not 
resolve the question about how to correct or otherwise deal with the 
inconsistent state in the child."
 The documentation suggests a workaround using fork handlers to be done in 
libgcj and not in my application.
 So I tried to forget the fork and launch 2 instances of the program by 
the shell and I've got the same results.
 It seems that the library libgcj.so is shared and synchronized.
 Follow the new version of the program without any fork.
 Please comments.
Temporal.
#include <iostream>
#include <string>
#include <unistd.h>
#include <gcj/cni.h>
#include <java/lang/Double.h>
#include <java/util/ArrayList.h>
using namespace std;
using namespace java::lang;
using namespace java::util;
int	main(int argc, char **argv)
{
	if (argc != 2)
	{
		cerr << "usage: integer" << endl;
		return 1;
	}
	cout << "begin" << endl;
	JvCreateJavaVM(NULL);
	JvAttachCurrentThread(NULL, NULL);
	ArrayList	*arrayList = new ArrayList;
	int	loopSize = atol(argv[1]);
	int	maxArraySize = loopSize >> 3;
	for(int	i = 0, j = 0; i < loopSize; i++, j++)
	{
		arrayList->add(new Double((jdouble)(double)i));
		if (j == maxArraySize)
		{
			j = 0;
			jint	size = arrayList->size();
			arrayList->clear();
			cout << getpid() << ", clear from " << (int)size << " to " << 
(int)arrayList->size() << endl;
		}
	}
	JvDetachCurrentThread();
	cout << "end" << endl;
	return 0;
}
>From: "Boehm, Hans" <hans.boehm@hp.com>
>To: "Ricardo Temporal" <ricardotemporal@hotmail.com>,<java@gcc.gnu.org>
>Subject: RE: performance problem with process fork in gcj compiled CNI
>Date: 2006年1月26日 11:47:21 -0800
>>I'm amazed it does anything useful at all.
>>Once you've created a JVM, your process is multithreaded. The fork()
>child only has one of those threads active, and is only allowed to call
>async-signal-safe functions until it performs an exec(). (See the SUSV3
>spec of fork().) You're not even close to satisfying those
>requirements.
>>Hans
>> > -----Original Message-----
> > From: java-owner@gcc.gnu.org [mailto:java-owner@gcc.gnu.org]
> > On Behalf Of Ricardo Temporal
> > Sent: Thursday, January 26, 2006 5:11 AM
> > To: java@gcc.gnu.org
> > Subject: performance problem with process fork in gcj compiled CNI
> >
> >
> > performance problem with process fork in gcj compiled CNI
> >
> > Hello,
> >
> > I have a simple C++ program with a main function that
> > fork itself's
> > process and then it starts a loop calling some processing in
> > java compiled
> > code, using CNI.
> >
> > I intend to split processing in a machine with 2 CPUs using fork
> > technology, I'm not able to use another solution.
> >
> > When I run the program without forking, it takes about T
> > seconds to
> > finish consuming 100% of CPU and 50% of the machine.
> >
> > When I run the program with a fork in the beginning, it
> > takes more than
> > 2T seconds to finish with each process consuming 100% of CPU and both
> > consuming 100% of the machine.
> >
> > What's happening ?
> >
> > Temporal.
> >
> > #include <iostream>
> > #include <string>
> > #include <sys/types.h>
> > #include <unistd.h>
> > #include <gcj/cni.h>
> > #include <java/lang/Double.h>
> > #include <java/util/ArrayList.h>
> >
> > using namespace std;
> > using namespace java::lang;
> > using namespace java::util;
> >
> > int globalVariable = 2;
> >
> > /*
> > 	Code Templates:
> >
> > 	http://www-personal.umich.edu/~rusekd/articles/soc_prelim.html
> > 	http://www.yolinux.com/TUTORIALS/ForkExecProcesses.html
> > */
> >
> > int	main(int argc, char **argv)
> > {
> > 	if (argc != 3)
> > 	{
> > 		cerr << "usage: integer bool" << endl;
> > 		return 1;
> > 	}
> >
> > 	cout << "begin" << endl;
> >
> > 	JvCreateJavaVM(NULL);
> > 	JvAttachCurrentThread(NULL, NULL);
> >
> > string sIdentifier;
> > int iStackVariable = 20;
> >
> > pid_t pID = (atol(argv[2]) ? fork() : 1);
> >
> > if (pID == 0) // child
> > {
> > // Code only executed by child process
> >
> > sIdentifier = "Child Process: ";
> > globalVariable++;
> > iStackVariable++;
> > }
> > else if (pID < 0) // failed to fork
> > {
> > cerr << "Failed to fork" << endl;
> > exit(1);
> > // Throw exception
> > }
> > else // parent
> > {
> > // Code only executed by parent process
> >
> > sIdentifier = "Parent Process:";
> > }
> >
> > // Code executed by both parent and child.
> >
> > cout << sIdentifier;
> > cout << " Global variable: " << globalVariable;
> > cout << " Stack variable: " << iStackVariable << endl;
> >
> > 	ArrayList	*arrayList = new ArrayList;
> >
> > 	int	loopSize = atol(argv[1]);
> > 	int	maxArraySize = loopSize >> 3;
> >
> > 	for(int	i = 0, j = 0; i < loopSize; i++, j++)
> > 	{
> > 		arrayList->add(new Double((jdouble)(double)i));
> >
> > 		if (j == maxArraySize)
> > 		{
> > 			j = 0;
> >
> > 			jint	size = arrayList->size();
> >
> > 			arrayList->clear();
> >
> > 			cout << pID << ", clear from " <<
> > (int)size << " to " <<
> > (int)arrayList->size() << endl;
> > 		}
> > 	}
> >
> > 	JvDetachCurrentThread();
> >
> > 	cout << "end" << endl;
> >
> > 	return 0;
> > }
> >
> >
> >



More information about the Java mailing list

AltStyle によって変換されたページ (->オリジナル) /