如何在调用sched_setaffinity()之后立即确保代码在指定的线程上运行,然后再等待cpu队列的下一个转弯?

问题描述 投票:-2回答:2

我已经编写了一个代码来制作除了父级之外的7个进程,所以总和是8 ...我设法使每个进程绑定到不同的线程...即我有intel core-i7 ..它有4个核心X 2个线程/核心= 8个线程...现在我的问题是如何确保在调用sched_setaffinity()之后,进程将继续在指定的处理器上运行,并且不会等到它在指定的cpu队列中的下一个转弯?我们可以有类似的东西吗?

get_me_out_of_the_current_queue_ so_that_the_sched_puts_me_in_the_ specified_queue_next_time()

我的代码是:

       #define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <sched.h>
#include <sys/shm.h>

int main()
{
   //code here in parent only , before any child start ///


   /////Declaration section////////
   pid_t ProcessIDs[8];
   cpu_set_t ThreadArray[8];
   int i ;
   int j ;
   int k ;
   int InternalPID;
   ////////////////////////////////


   /////Initialization section/////
   i=1;
   j=0;
   k=0;
   InternalPID = 0;

   for (j=0;j<8;j++)
   {
   ProcessIDs[j] = 0;
   }

   for (j=0;j<8;j++)
   {
   CPU_ZERO(&ThreadArray[j]);
   }

   for (j=0;j<8;j++)
   {
   CPU_SET(j+1,&ThreadArray[j]);
   }
   /////////////////////////////////



///////// shm ///////////////////////////////
int  shmid ;
int err;
char *shm;
shmid = shmget(IPC_PRIVATE,8 ,IPC_CREAT | IPC_EXCL | 0666 );
shm=shmat(shmid,0, IPC_CREAT | IPC_EXCL | 0666  );
if (shmid > -1)
{
printf("shared memory created succefully\n");
}
int m =0;
for(m=0 ;m<8;m++)
{
    shm[m]='N';
}
//////////////////////////////////////////////



   /////// Parent only - children don't exist//////


   ProcessIDs[0] = getpid();
   while( (getpid() == ProcessIDs[0] ) & (i < 8) )
   {
   ProcessIDs[i] = fork();
   i++;
   }

    ////////////////////////////////////////////////

    ////////parent only - children exist////////////
    if(getpid() == ProcessIDs[0])
    {
    for(k=0;k<8;k++)
    {
    sched_setaffinity(ProcessIDs[k],sizeof(cpu_set_t),&ThreadArray[k]);
    shm[k] = 'Y';
    sleep(2);
    }
    }
    ////////////////////////////////////////////////


   ///////////////////parent and children////
   for(k=1;k<8;k++)
   {
    if(ProcessIDs[k] == 0){
    InternalPID = k;
    break;
    }
   }
   //////////////////////////////////////////////

   //////////Process Specific code //////////////

   if (InternalPID == 0)
   {
   ////// Parent only Rest of Code ////////
   while(shm[0] != 'Y');
   printf("hello for parent %i.. \n",InternalPID);
   return 0 ;
   ////////////////////////////////////////
   }
   else if (InternalPID == 1)
   {
   ////////////// child 1 /////////////////
   while(shm[1] != 'Y');
   printf("hello for child  %i.. \n", InternalPID);
   return 0 ;
   ////////////////////////////////////////
   }
   else if (InternalPID == 2)
   {
   ////////////// child 2 /////////////////
   while(shm[2] != 'Y');
   printf("hello for child  %i.. \n", InternalPID);
   return 0 ;
   ////////////////////////////////////////
   }
   else if (InternalPID == 3)
   {
   ////////////// child 3 /////////////////
   while(shm[3] != 'Y');
   printf("hello for child  %i.. \n", InternalPID);
   return 0 ;
   ////////////////////////////////////////
   }
   else if (InternalPID == 4)
   {
   ////////////// child 4 /////////////////
   while(shm[4] != 'Y');
   printf("hello for child  %i.. \n", InternalPID);
   return 0 ;
   ////////////////////////////////////////
   }
   else if (InternalPID == 5)
   {
   ////////////// child 5 /////////////////
   while(shm[5] != 'Y');
   printf("hello for child  %i.. \n", InternalPID);
   return 0 ;
   ////////////////////////////////////////
   }
   else if (InternalPID == 6)
   {
   ////////////// child 6 /////////////////
   while(shm[6] != 'Y');
   printf("hello for child  %i.. \n", InternalPID);
   ////////////////////////////////////////
   }
   else if (InternalPID == 7)
   {
   ////////////// child 7 /////////////////
   while(shm[7] != 'Y');
   printf("hello for child  %i.. \n", InternalPID);
   return 0 ;
   ////////////////////////////////////////
   }
   /////////////////////////////////////////////////




   ///////////////////////////////////////////////////////
}

我知道while()循环在每个进程特定代码的开头(在if分支内)可以保证,但我想这是由于时间的延迟,这不是一个强大的解决方案...请告诉我什么是解决这个问题的正确方法......

第二点我想问一下:

8个进程的每个进程将在不同的核心上运行,但是在进程间通信期间,例如当我继续并创建管道以便进程通过父进程通信时,如中间点“就像星形拓扑结构”如果孩子说孩子想要的话会发生什么在它的会话期间进行通信 - 当它仍然在它的cpu队列当前没有像childA那样运行时...操作系统的作用是让所有八个进程感觉好像每个进程当前只有cpu一样?

c multithreading affinity
2个回答
0
投票

我的问题如何确保在调用sched_setaffinity()之后,进程将继续在指定的处理器上运行,并且不会等到指定的cpu队列中的下一个转弯?

The docs确实说,部分:

如果pid指定的进程当前未在mask中指定的某个CPU上运行,则该进程将迁移到mask中指定的其中一个CPU。

这并不保证这样的迁移会在该进程的当前时间片(如果有的话)到期之前发生,也不会立即开始在其中一个指定的CPU上运行,但这没有实际意义,因为你怎么能告诉它?

如果一个孩子说孩子想要通信 - 在它的会话期间 - 父母 - 当它仍然在它的cpu队列当前没有像childA那样运行时...会发生操作系统使所有八个过程感觉好像每个人目前只有cpu吗?

显然,当一个进程当前没有在CPU上进行调度时,它根本无法执行任何操作。事实上,它甚至不能(隐喻地)设想想要做任何事情。但总的来说,是的,OS是调解时间共享和IPC的角色。

这与CPU亲和性或系统中物理执行单元的数量没有任何关系。所有这些都可以在单核机器上正常工作(尽管在这样的机器上设置CPU亲和力毫无意义)。


1
投票

简而言之 - 你不能,因为你所要求的核心可能已经忙于做其他事情。设置关联性所做的就是告诉操作系统您只希望在该特定CPU上安排进程。因此,实际上更有可能将您的任务延迟到默认关联(任何CPU)将在第一个可用时安排它的位置。

您可以提高进程优先级(即实时调度),这将导致进程抢占已经在CPU上运行的任何内容,这可能更符合您的预期。

话虽这么说,你可能会完全锁定你的系统,如果“while”循环永远不会结束,它们将被困在一个紧密的循环中,没有其他任何东西将被安排(甚至你的shell),所以你将无法阻止它们。

© www.soinside.com 2019 - 2024. All rights reserved.