2012-02-09 7 views
13

Şu anda Linux programlayıcısı hakkında çalışıyorum.Her işlem, zamanlayıcı tarafından belirli bir çekirdeğe nasıl sabitlenir (Linux)

1) nasıl bir çekirdeğe her işlem (iplik) tutturulmuş: işlemci çekirdek afinite ile ilgili olarak, aşağıdaki bilmek isteyen?

bir işlem yürütülür olan çekirdek afinite değiştirmek için bir sistem çağrısı sched_setaffinity vardır. Fakat dahili olarak, bir süreç (veya bir iplik) oluşturulduğunda, varsayılan Linux zamanlayıcısı belirli bir çekirdeğe (iş parçacığı) nasıl atanır? Bir çekirdekten diğerine taşınmakta olan görev hakkında bilgi vermek için sched_setaffinity sistem çağrısı değiştirdim.

printk(KERN_INFO "%d %d %ld %lu %s\n", current->pid, current->tgid, 
             current->state, current->cpus_allowed, 
             current->comm); 

O /var/log/messages yukarıdaki bilgilerin hiçbir dökümü olduğu görülmektedir. Böylece, varsayılan zamanlayıcı her işlemi farklı bir şekilde işaretler, ancak nasıl olduğunu anlayamıyorum.

2) Çekirdek kimliğini PID veya başka bir bilgi ile almak mümkün mü?

Linux çekirdeği içinde uygulamak istediğim şey budur. task_struct'da cpus_allowed adlı bir üye var. Ancak bu, çekirdek kimliği değil, yakınlık ayarlayan bir maskedir. Belirtilen işlemin çalıştığı çekirdeği tanımlayan bir veri almak istiyorum.

Teşekkürler,

cevap

0

CPU çekirdek yakınlığı, OS'ye özgüdür. OS bunu nasıl yapacağını biliyor, zorunda değilsiniz. Hangi çekirdeğin çalışacağını belirttiyseniz, bazı süreçlere girebilirdiniz, bunların bir kısmı işlemi yavaşlatabilirdi. Çekirdeğe, cpu_allowed bit maskesi alanı içeren task_struct işlemleri ile ortaya çıkan veri yapısında

. Bu, makinedeki her n işlemci için bir bit içerir. Dört fiziksel çekirdeğe sahip bir makinenin dört biti olur. Eğer bu CPU çekirdeği hiper-yüzdeli etkinse, sekiz bitlik bir bit maskesi olacaktır. Belirli bir işlem için belirli bir bit ayarlanmışsa, bu işlem ilişkili çekirdek üzerinde çalışabilir. Bu nedenle, bir işlem herhangi bir çekirdek üzerinde çalışmasına izin verilir ve gerektiğinde işlemciye geçiş izni verilirse, bit maskesi tamamen 1 olur. Bu aslında Linux altındaki süreçler için varsayılan durumdur. Örneğin,

PID 2441: PRIO 0, POLICY N: SCHED_NORMAL, NICE 0, AFFINITY 0x3 

işlem 2441 daha Core0 ve Core1 kullanılan anlamına gelir 0x3 bir CPU yakınlık vardır.

uygulamalar da/belirtmek bit maskesi değiştirilmesiyle çekirdek API sched_set_affinity() kullanılarak afinite ayarlayabilirsiniz.

+0

Cevabınız için teşekkür ederiz. Ama istediğim bu farklı. Açıklamanızın yanıltıcı olup olmadığını merak ediyordum ... Öncelikle, kullanıcı alanında çalışan bir uygulama yaratmadığım için 'sched_setaffinity' sistem çağrısı kullanmıyorum (sched_set_affinity değil, sched_setaffinity). – akry

+0

İkincisi, 'cpus_allowed' (cpu_allowed değil) alanı, işlemin çalıştığı CPU çekirdeğini tanımlamak için yeterli bilgi değildir. cpus_allowed varsayılan olarak 1 olarak ayarlanır, böylece işlem mevcut tüm çekirdekleri taşıyacaktır. Sürecin çalıştığı yeri belirten herhangi bir alan/yöntem varsa, gerçekten bilmek istediğim şey budur. – akry

+0

Neyse, sorumu cevapladığınız için teşekkür ederim. – akry

4

Her işlemci kendi runqueue vardır AFAIK biz bunun için ait olduğu runqueue bakarak sürecinin mevcut CPU öğrenebilirsiniz. task_struct *p verildiğinde, onun runqueue değerini struct rq = task_rq(p) yapabiliriz ve struct rq'nin cpu isimli bir alanı vardır, sanırım bu cevap olmalı.

Bunu pratikte denemedim, sadece çevrimiçi bir kod oku, ve bunun işe yarayıp yaramadığından emin değilim. Keşke yardımcı olabilir. /proc/pid/stat içinde

+0

Cevabınız için teşekkür ederiz. Bu yöntemi denedikten sonra size bildireceğim. – akry

+1

Bunun kıpır kıpır olduğunu unutmayın - görev, bir koşu yerinden diğerinizden bir başkasına geçirilebilir. – caf

2

Alan 39 işlemin geçerli çekirdek/cpu anlatır.

ör .:

#cat /proc/6128/stat 
6128 (perl) S 3390 6128 3390 34821 6128 4202496 2317 268 0 0 1621 59 0 0 16 0 1 0 6860821 10387456 1946 18446744073709551615 1 1 0 0 0 0 0 128 0 18446744073709551615 0 0 17 8 0 0 0 

işlem 6128 çekirdek 8 çalışıyor.

2

Bir iş parçacığı, task_struct kullanarak çalıştığı işlemci kimliğini belirleyebilir:

#include <linux/sched.h> 

task_struct *p; 
int cpu_id = task_cpu(p);