Linux 커널 4.4.0-57에서 C++ 11을 사용하여 고정 된 두 개의 루 프 루핑 프로세스 (예 : p1, p2)를 고정하려고합니다 (pthread_setaffinity_np)을 사용하고 POSIX 세마포어 (세마포어 h)와 sched_yield()을 사용하여 인터리빙 실행 순서를 확인하십시오. 하지만 잘 돌아 가지 않았습니다.POSIX 세마포어가 높은 경쟁 상태/부하에서 작동하지 않습니다.
다음은 2 개의 프로세스를 생성하고 각각이 하위 작업 코드를 실행하는 상위 코드 (상위 작업)입니다.
#include <stdio.h>
#include <cstdlib>
#include <errno.h> // errno
#include <iostream> // cout cerr
#include <semaphore.h> // semaphore
#include <fcntl.h> // O_CREAT
#include <unistd.h> // fork
#include <string.h> // cpp string
#include <sys/types.h> //
#include <sys/wait.h> // wait()
int init_semaphore(){
std::string sname = "/SEM_CORE";
sem_t* sem = sem_open (sname.c_str(), O_CREAT, 0644, 1);
if (sem == SEM_FAILED) {
std::cerr << "sem_open failed!\n";
return -1;
}
sem_init(sem, 0, 1);
return 0;
}
// Fork and exec child-task.
// Return pid of child
int fork_and_exec(std::string pname, char* cpuid){
int pid = fork();
if (pid == 0) {
// Child
char* const params[] = { "./child-task", "99", strdup(pname.c_str()), cpuid, NULL };
execv(params[0], params);
exit(0);
}
else {
// Parent
return pid;
}
}
int main(int argc, char* argv[]) {
if (argc <= 1)
printf("Usage ./parent-task <cpuid> \n");
char* cpuid = argv[1];
std::string pnames[2] = { "p111", "p222" };
init_semaphore();
int childid[ 2 ] = { 0 };
int i = 0;
for(std::string pname : pnames){
childid[ i ] = fork_and_exec(pname, cpuid);
}
for (i=0; i<2; i++)
if (waitpid(childid[i], NULL, 0) < 0)
perror("waitpid() failed.\n");
return 0;
}
아이 태스크 코드는 다음과 같습니다 : 아이 태스크 코드에서
#include <cstdlib>
#include <stdio.h>
#include <sched.h>
#include <pthread.h>
#include <stdint.h>
#include <errno.h>
#include <semaphore.h>
#include <iostream>
#include <sys/types.h>
#include <fcntl.h> // O_CREAT
sem_t* sm;
int set_cpu_affinity(int cpuid) {
pthread_t current_thread = pthread_self();
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(cpuid, &cpuset);
return pthread_setaffinity_np(current_thread,
sizeof(cpu_set_t), &cpuset);
}
int lookup_semaphore() {
sm = sem_open("/SEM_CORE", O_RDWR);
if (sm == SEM_FAILED) {
std::cerr << "sem_open failed!" << std::endl ;
return -1;
}
}
int main(int argc, char* argv[]) {
printf("Usage: ./child-task <PRIORITY> <PROCESS-NAME> <CPUID>\n");
printf("Setting SCHED_RR and priority to %d\n", atoi(argv[1]));
set_cpu_affinity(atoi(argv[3]));
lookup_semaphore();
int res;
uint32_t n = 0;
while (1) {
n += 1;
if (!(n % 1000)) {
res = sem_wait(sm);
if(res != 0) {
printf(" sem_wait %s. errno: %d\n", argv[2], errno);
}
printf("Inst:%s RR Prio %s running (n=%u)\n", argv[2], argv[1], n);
fflush(stdout);
sem_post(sm);
sched_yield();
}
sched_yield();
}
sem_close(sm);
}
, 내가 기다리고 세마포어를 올리기에 경합/부하를 줄이는 실험
if (!(n % 1000))
있습니다. 내가 얻은 결과는
n % 1000
일 때 자식 프로세스 중 하나가 항상 잠자기 상태 (
상위)이고 다른 자식 프로세스가 제대로 실행된다는 것입니다. 그러나,로드/경쟁이 적은
n % 10000
을 설정하면 두 프로세스가 모두 실행되어 출력이 인터리빙 방식으로 출력되므로 이는 예상 한 결과입니다.
이것이 semaphore.h의 제한 사항인지 또는 프로세스 실행 순서를 보장하는 더 나은 방법이 있는지 알고 계십니까?
'main'에있는 어린이의 의견에서 알 수 있듯이 예약 정책과 우선 순위를 설정 하시겠습니까? 그것들을 어디에서 설정한다는 것은 무엇입니까? – pilcrow