2011-01-04 6 views
3

Ich bin besonders interessant dabei unter Linux, in Bezug auf Java-Programme. Es gibt bereits einige Fragen, die sagen, dass Sie keine Kontrolle über Java haben und einige RFEs von Sun/Oracle geschlossen wurden.Kann verhindert werden, dass Kinder die CPU/Core-Affinität des Elternteils erben?

Wenn Sie Zugriff auf den Quellcode haben und eine Low-Level-Sprache verwenden, können Sie sicher die entsprechenden Systemaufrufe tätigen. Sandbox-Systeme - möglicherweise ohne Quellcode - sind jedoch eine größere Herausforderung. Ich hätte gedacht, dass ein Werkzeug, um diesen pro-Prozess oder einen Kernel-Parameter zu setzen, in der Lage ist, dies von außerhalb des Elternprozesses zu steuern. Das ist wirklich was ich suche.

Ich verstehe die reason why this is the default. Es sieht aus wie eine Version von Windows may allow some control davon, aber die meisten nicht. Ich habe damit gerechnet, dass Linux die Kontrolle darüber hat, aber scheint wie it's not an option.

Antwort

1

Sofern Sie über ausreichende Berechtigungen verfügen, können Sie einfach sétaffinity aufrufen, bevor Sie das Kind ausführen. Mit anderen Worten, von

if (fork() == 0) 
     execve("prog", "prog", ...); 

bewegen

/* simple example using taskset rather than setaffinity directly */ 
if (fork() == 0) 
     execve("taskset", "taskset", "-c", "0-999999", ...); 

[Natürlich zu verwenden mit 999999 ist nicht schön, aber das kann durch ein Programm ersetzt werden, die automatisch die Anzahl der CPUs bestimmt und setzt die Affinität Maske wie gewünscht.]

+0

Aber nur mit Zugriff auf (nicht Sandboxed) Quellcode, richtig? –

+0

Wenn Sie eine Möglichkeit haben, zu beeinflussen, welches Kindprogramm ausgeführt wird (z. B. Konfigurationsdatei - es benötigt nicht immer eine Programmquelle), können Sie es tun. Wenn es kein, naja, "falsches Programm" gibt ;-) – user562374

1

Was Sie auch tun könnten, ist die Affinität des Kindes vom Elternteil nach dem fork() zu ändern. Übrigens, ich nehme an, dass Sie auf Linux sind, einige dieser Dinge, wie das Abrufen der Anzahl der Kerne mit sysconf() wird auf verschiedenen Betriebssystemen und UNIX-Varianten anders sein .... Das Beispiel hier, bekommt die CPU des übergeordneten Prozesses und versucht sicherzustellen, dass alle untergeordneten Prozesse in einem Round-Robin auf einem anderen Kern geplant sind.

/* get the number of cpu's */ 
numcpu = sysconf(_SC_NPROCESSORS_ONLN); 

/* get our CPU */ 
CPU_ZERO(&mycpuset); 
sched_getaffinity(getpid() , sizeof mycpuset , &mycpuset); 

for(i=0 ; i < numcpu ; i++) 
{ 
    if(CPU_ISSET(i, &mycpuset)) 
    { 
     mycpu = i; 
     break; 
    } 
} 

//... 

while(1) 
{ 
    //Some other stuff..... 

    /* now the fork */  
    if((pid = fork()) == 0) 
    { 
     //do your child stuff 
    }  

    /* Parent... can schedule child. */ 
    else 
    { 
    cpu = ++cpu % numcpu; 
     if(cpu == mycpu) 
      cpu = ++cpu % numcpu; 
     CPU_ZERO(&mycpuset); 
     CPU_SET(cpu,&mycpuset); 
     /*set processor affinity*/ 
     sched_setaffinity(pid, sizeof mycpuset, &mycpuset); 

     //any other father stuff 
    } 
} 
+0

Wie bei der anderen Antwort funktioniert das nicht in Sandbox-Umgebungen (oder - nervig aber weniger problematisch - ohne Zugriff auf Quellcode). Ich suche nach einer Möglichkeit, dies von außerhalb des Prozesses (Kernel-Einstellung, Taskset usw.) zu tun. –

+1

@ sam-brightman Vielleicht habe ich die Frage nicht verstanden, aber ich verstehe wirklich nicht, warum ** Taskset ** es nicht für dich schneidet. Und wenn Sie dies programmgesteuert durchführen möchten, wie im Abschnitt "Notizen" der Hilfeseite sched_affinity erläutert, erbt ein über fork (2) erstelltes Kind die CPU-Affinitätsmaske des übergeordneten Elements. Die Affinitätsmaske wird über einen Execve (2) beibehalten. Wenn Sie also einen Prozess über Execve starten möchten, ist das auch möglich. Wenn Sie die PID kennen, können Sie mit sched_setaffinity definitiv die Kernaffinität festlegen. In einer Sandbox (** chroot **) sollte sich wirklich nichts ändern. – truthbk