.\" -*- coding: UTF-8 -*-
.\" Copyright 2002, Robert Love <rlove@rlove.org>
.\" Copyright 2006-2015, Michael Kerrisk <mtk.manpages@gmail.com>
.\" Copyright, the authors of the Linux man-pages project
.\"
.\" SPDX-License-Identifier: GPL-2.0-or-later
.\"
.\"*******************************************************************
.\"
.\" This file was generated with po4a. Translate the source file.
.\"
.\"*******************************************************************
.TH sched_setaffinity 2 "8 lutego 2026 r." "Linux man\-pages 6.17" 
.SH NAZWA
sched_setaffinity, sched_getaffinity \- ustawia i pobiera maskę koligacji
procesora dla wątku
.SH BIBLIOTEKA
Standardowa biblioteka C (\fIlibc\fP,\ \fI\-lc\fP)
.SH SKŁADNIA
.nf
\fB#define _GNU_SOURCE\fP             /* Patrz feature_test_macros(7) */
\fB#include <sched.h>\fP
.P
\fBint sched_setaffinity(pid_t \fP\fIpid\fP\fB, size_t \fP\fIcpusetsize\fP\fB,\fP
\fB                      const cpu_set_t *\fP\fImask\fP\fB);\fP
\fBint sched_getaffinity(pid_t \fP\fIpid\fP\fB, size_t \fP\fIcpusetsize\fP\fB,\fP
\fB                      cpu_set_t *\fP\fImask\fP\fB);\fP
.fi
.SH OPIS
Maska koligacji procesora wątku określa zbiór procesorów, na których może on
działać. W systemach wieloprocesorowych ustawiając maskę koligacji procesora
można, w określonych sytuacjach, zyskać na wydajności. Na przykład
przeznaczając jeden procesor na dany wątek (tj. ustawiając maskę koligacji
tego wątku tak, aby określała pojedynczy procesor i ustawiając maskę
koligacji wszystkich innych wątków tak, aby pomijała ten procesor) można
zapewnić maksymalną szybkość wykonywania danego wątku. Ograniczenie
możliwości działania wątku do pojedynczego procesora pozwala też na
uniknięcie narzutu wynikającego z unieważniania bufora zachodzącego, gdy
wątek przestaje być wykonywany na jednym procesorze, a następnie wznawia
wykonywanie na kolejnym.
.P
Maska koligacji procesora jest reprezentowana przez strukturę \fIcpu_set_t\fP,
\[Bq]zbiór procesorów\[rq], na którą wskazuje \fImask\fP. Zbiór makr do
operowania na zbiorach procesorów opisano w podręczniku \fBCPU_SET\fP(3).
.P
\fBsched_setaffinity\fP() ustawia maskę koligacji procesora wątku o
identyfikatorze \fIpid\fP, na wartość określoną przez \fImask\fP. Jeśli \fIpid\fP
wynosi zero, używany jest wątek wywołujący. Argument \fIcpusetsize\fP jest
długością (w bajtach) danych, na które wskazuje \fImask\fP. Argument ten zwykle
należy podać jako \fIsizeof(cpu_set_t)\fP.
.P
Jeśli wątek podany w \fIpid\fP nie działa obecnie na jednym z procesorów
określonych w \fImask\fP, to wątek ten zostanie zmigrowany na jeden z
procesorów określonych w \fImask\fP.
.P
\fBsched_getaffinity\fP() zapisuje maskę koligacji procesora wątku o
identyfikatorze \fIpid\fP do struktury \fIcpu_set_t\fP, na którą wskazuje
\fImask\fP. Argument \fIcpusetsize\fP określa rozmiar \fImask\fP (w bajtach). Jeśli
\fIpid\fP wynosi zero, wywołanie zwraca maskę wątku wywołującego.
.SH "WARTOŚĆ ZWRACANA"
W przypadku powodzenia, \fBsched_setaffinity\fP() i \fBsched_getaffinity\fP()
zwracają 0 (lecz zob. \[Bq]Różnice biblioteki C/jądra\[rq] poniżej, gdzie
opisano różnice w zwracanej wartości w podległym \fBsched_getaffinity\fP()). W
razie wystąpienia błędu zwracane jest \-1 i ustawiane \fIerrno\fP, wskazując
błąd.
.SH BŁĘDY
.TP 
\fBEFAULT\fP
Podany adres pamięci był nieprawidłowy.
.TP 
\fBEINVAL\fP
Maska bitowa koligacji \fImask\fP nie zawierała żadnego procesora obecnego
fizycznie w systemie, który jest jednocześnie dozwolony do użycia przez
wątek, biorąc pod uwagę wszelkie ograniczenia, jakie mogą wynikać z grup
kontrolnych \fIcpuset\fP i mechanizmu \[Bq]cpuset\[rq] opisanego w podręczniku
\fBcpuset\fP(7).
.TP 
\fBEINVAL\fP
(\fBsched_getaffinity\fP() i, przed Linuksem 2.6.9, \fBsched_setaffinity\fP())
\fIcpusetsize\fP jest mniejszy od rozmiaru maski koligacji używanego przez
jądro.
.TP 
\fBEPERM\fP
(\fBsched_setaffinity\fP()) Wątek wywołujący nie ma odpowiednich
przywilejów. Wywołujący musi mieć efektywny identyfikator użytkownika równy
rzeczywistemu identyfikatorowi użytkownika albo efektywnemu identyfikatorowi
użytkownika wątku podanego w \fIpid\fP, albo musi posiadać przywilej
\fBCAP_SYS_NICE\fP w przestrzeni nazw użytkownika wątku podanego w \fIpid\fP.
.TP 
\fBESRCH\fP
Nie znaleziono wątku o identyfikatorze równym \fIpid\fP.
.SH STANDARDY
Linux.
.SH HISTORIA
Linux 2.5.8, glibc 2.3.
.P
Początkowo, intefejsy glibc ujęte w argumencie \fIcpusetsize\fP były typu
\fIunsigned int\fP. W glibc 2.3.3, usunięto argument \fIcpusetsize\fP, jednak
przywrócono go w glibc 2.3.4, tym razem jako \fIsize_t\fP.
.SH UWAGI
Po wywołaniu do \fBsched_setaffinity\fP(), zbiór procesorów, na których wątek
faktycznie będzie uruchomiony, jest iloczynem zbioru podanego w argumencie
\fImask\fP oraz zbioru procesorów faktycznie obecnych w systemie. System może
dodatkowo ograniczyć zbiór procesorów, na których działa wątek, jeśli
używany jest mechanizm \[Bq]cpuset\[rq] opisany w podręczniku
\fBcpuset\fP(7). Ograniczenia te, dotyczące faktycznego zbioru procesorów, na
których wątek będzie działał, są ezgekwowane po cichu przez jądro.
.P
Istnieje wiele sposobów na sprawdzenie liczby procesorów dostępnych w
systemie, w tym: sprawdzenie zawartości \fI/proc/cpuinfo\fP; skorzystanie z
\fBsysconf\fP(3) do pozyskania wartości parametrów \fB_SC_NPROCESSORS_CONF\fP i
\fB_SC_NPROCESSORS_ONLN\fP  oraz sprawdzenie listy katalogów procesorów w
\fI/sys/devices/system/cpu/\fP.
.P
Podręcznik \fBsched\fP(7) zawiera opis szeregowania zadań w Linuksie.
.P
Maska koligacji procesora jest atrybutem przynależnym wątkowi, który można
dostosować niezależnie dla każdego wątku w grupie wątków. Wartość zwracaną z
wywołania do \fBgettid\fP(2) można przekazać w argumencie \fIpid\fP. Określenie
\fIpid\fP jako 0 ustawi atrybut wątku wywołującego, a przekazanie wartości
zwróconej z wywołania do \fBgetpid\fP(2) ustawi atrybut głównego wątku w grupie
wątków. Jeśli korzysta się z interfejsu wątków POSIX, zamiast
\fBsched_setaffinity\fP() należy stosować \fBpthread_setaffinity_np\fP(3).
.P
Za pomocą opcji rozruchowej \fIisolcpus\fP można wyizolować jeden lub więcej
procesorów przy rozruchu, dzięki czemu żadne procesy nie zostaną na nich
uruchomione. Po zastosowaniu tej opcji rozruchowej, jedynym sposobem
przydzielenia wątków na wyizolowane procesory jest mechanizm \fBcpuset\fP(7)
lub \fBsched_setaffinity\fP(). Więcej informacji znajduje się w pliku
\fIDocumentation/admin\-guide/kernel\-parameters.txt\fP w źródłach jądra. Jak
wskazano w tym pliku, preferowanym sposobem izolowania procesorów jest
\fIisolcpus\fP (w porównaniu do alternatywy, w postaci ręcznego ustawiania
koligacji procesorów dla wszystkich procesów w systemie).
.P
Potomek utworzony za pomocą \fBfork\fP(2) dziedziczy maskę koligacji procesora
swojego rodzica. Maska koligacji jest zachowywana poprzez \fBexecve\fP(2).
.SS "Różnice biblioteki C/jądra"
Niniejszy podręcznik opisuje interfejs glibc wywołań koligacji
procesora. Rzeczywisty interfejs wywołania systemowego jest nieco odmienny,
ponieważ \fImask\fP jest typu \fIunsigned long\ *\fP, odzwierciedlając fakt, że
podległa implementacja zbiorów procesorów jest prostą maską bitową.
.P
W przypadku powodzenia, surowe wywołanie systemowe \fBsched_getaffinity\fP()
zwraca liczbę umieszczonych bajtów, skopiowanych do bufora \fImask\fP; będzie
to mniejsza z: \fIcpusetsize\fP oraz rozmiaru (w bajtach) typu danych
\fIcpumask_t\fP, który służy wewnętrznie w jądrze do reprezentacji maski
bitowej zbioru procesorów.
.SS "Obsługa systemów z dużymi maskami koligacji procesora"
.\" FIXME . See https://sourceware.org/bugzilla/show_bug.cgi?id=15630
.\" and https://sourceware.org/ml/libc-alpha/2013-07/msg00288.html
Podległe wywołanie systemowe (reprezentujące maski procesorów jako maski
bitowe typu \fIunsigned long\ *\fP) nie nakładają ograniczeń na rozmiar masek
procesorów. Jednak typ danych \fIcpu_set_t\fP używany przez bibliotekę glibc ma
stały rozmiar 128 bajtów co oznacza, że maksymalny numer procesora jaki może
odwzorować to 1023. Jeśli maska koligacji procesora jest większa niż 1024,
wywołanie w postaci:
.P
.in +4n
.EX
sched_getaffinity(pid, sizeof(cpu_set_t), &mask);
.EE
.in
.P
zawiedzie z błędem \fBEINVAL\fP, błędem z poziomu podległego wywołania
systemowego stosowanym w przypadku, gdy rozmiar \fImask\fP podany w
\fIcpusetsize\fP jest mniejszy od rozmiaru maski koligacji używanego przez
jądro (w zależności od systemowej topologii procesorów, maska koligacji
jądra może być znacznie większa od liczby aktywnych procesorów w systemie).
.P
Przy pracy w systemach o dużych maskach koligacji procesora w jądrze, należy
dynamicznie przydzielać argument \fImask\fP (zob. \fBCPU_ALLOC\fP(3)). Obecnie,
jedynym sposobem na to, jest sprawdzenie rozmiaru wymaganej maski za pomocą
wywołań \fBsched_getaffinity\fP() o coraz większych rozmiarach masek (do
momentu zwrócenia przez wywołanie błędu \fBEINVAL\fP).
.P
Proszę zauważyć, że \fBCPU_ALLOC\fP(3) może przydzielić nieco większy zbiór
procesorów niż zażądano (ponieważ zbiory procesorów zaimplementowano jako
maski bitowe, korzystające z \fIsizeof(long)\fP jako jednostki). Zatem
\fBsched_getaffinity\fP() może ustawiać bity poza zażądanym rozmiarem alokacji,
ponieważ jądro widzi kilka dodatkowych bitów. Wywołujący powinien zatem
iterować bity w zwróconym zbiorze, licząc które z nich są ustawione i
zatrzymując się po osiągnięciu wartości zwróconej przez \fBCPU_COUNT\fP(3)
(zamiast iterować po liczbie bitów, których alokacji zażądano).
.SH PRZYKŁADY
Poniższy program tworzy proces potomny. Procesy macierzysty i potomny
następnie przydzielają się na określony procesor i wykonują identyczne
pętle, które zabierają jakiś czas procesora. Przed zakończeniem, rodzic
czeka na ukończenie procesu potomnego. Program przyjmuje trzy argumenty
wiersza poleceń: numer procesora dla rodzica, numer procesora dla potomka i
liczbę iteracji pętli, jakie mają wykonać oba procesy.
.P
Jak pokazuje niżej przykładowe wykonanie, ilość czasu rzeczywistego i czasu
procesora działającego programu zależy od buforowania na poziomie wewnątrz
rdzenia i od tego, czy procesy używają tego samego procesora.
.P
Najpierw korzystamy z \fBlscpu\fP(1) sprawdzając, że dany system (x86) ma dwa
rdzenie, każdy z dwoma procesorami:
.P
.in +4n
.EX
$\fB lscpu | egrep \-i \[aq]core.*:|socket\[aq]\fP;
Wątków na rdzeń:       2
Rdzeni na gniazdo:     2
Gniazd:                1
.EE
.in
.P
Następnie mierzymy czas działania przykładowego programu dla trzech
przypadków: gdy oba procesy działają na tym samym procesorze; gdy procesy
działają na różnych procesorach na tym samym rdzeniu; gdy procesy działają
na różnych procesorach na różnych rdzeniach.
.P
.in +4n
.EX
$\fB time \-p ./a.out 0 0 100000000\fP;
real 14.75
user 3.02
sys 11.73
$\fB time \-p ./a.out 0 1 100000000\fP;
real 11.52
user 3.98
sys 19.06
$\fB time \-p ./a.out 0 3 100000000\fP;
real 7.89
user 3.29
sys 12.07
.EE
.in
.SS "Kod źródłowy programu"
.\" SRC BEGIN (sched_setaffinity.c)
\&
.EX
#define _GNU_SOURCE
#include <err.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
\&
int
main(int argc, char *argv[])
{
    int           parentCPU, childCPU;
    cpu_set_t     set;
    unsigned int  nloops;
\&
    if (argc != 4) {
        fprintf(stderr, "Użycie: %s cpu\-rodzica cpu\-potomka l\-pętli\[rs]n",
                argv[0]);
        exit(EXIT_FAILURE);
    }
\&
    parentCPU = atoi(argv[1]);
    childCPU = atoi(argv[2]);
    nloops = atoi(argv[3]);
\&
    CPU_ZERO(&set);
\&
    switch (fork()) {
    case \-1:            /* Błąd */
        err(EXIT_FAILURE, "fork");
\&
    case 0:             /* Potomek */
        CPU_SET(childCPU, &set);
\&
        if (sched_setaffinity(0, sizeof(set), &set) == \-1)
            err(EXIT_FAILURE, "sched_setaffinity");
\&
        for (unsigned int j = 0; j < nloops; j++)
            getppid();
\&
        exit(EXIT_SUCCESS);
\&
    default:            /* Rodzic */
        CPU_SET(parentCPU, &set);
\&
        if (sched_setaffinity(0, sizeof(set), &set) == \-1)
            err(EXIT_FAILURE, "sched_setaffinity");
\&
        for (unsigned int j = 0; j < nloops; j++)
            getppid();
\&
        wait(NULL);     /* Oczekiwanie na zakończenie potomka */
        exit(EXIT_SUCCESS);
    }
}
.EE
.\" SRC END
.SH "ZOBACZ TAKŻE"
.ad l
.nh
\fBlscpu\fP(1), \fBnproc\fP(1), \fBtaskset\fP(1), \fBclone\fP(2), \fBgetcpu\fP(2),
\fBgetpriority\fP(2), \fBgettid\fP(2), \fBnice\fP(2), \fBsched_get_priority_max\fP(2),
\fBsched_get_priority_min\fP(2), \fBsched_getscheduler\fP(2),
\fBsched_setscheduler\fP(2), \fBsetpriority\fP(2), \fBCPU_SET\fP(3),
\fBget_nprocs\fP(3), \fBpthread_setaffinity_np\fP(3), \fBsched_getcpu\fP(3),
\fBcapabilities\fP(7), \fBcpuset\fP(7), \fBsched\fP(7), \fBnumactl\fP(8)
.PP
.SH TŁUMACZENIE
Tłumaczenie niniejszej strony podręcznika:
Michał Kułach <michal.kulach@gmail.com>
.
.PP
Niniejsze tłumaczenie jest wolną dokumentacją. Bliższe informacje o warunkach
licencji można uzyskać zapoznając się z
.UR https://www.gnu.org/licenses/gpl-3.0.html
GNU General Public License w wersji 3
.UE
lub nowszej. Nie przyjmuje się ŻADNEJ ODPOWIEDZIALNOŚCI.
.PP
Błędy w tłumaczeniu strony podręcznika prosimy zgłaszać na adres listy
dyskusyjnej
.MT manpages-pl-list@lists.sourceforge.net
.ME .
