【问题标题】:Creating a process pool C Linux创建进程池 C Linux
【发布时间】:2017-10-12 14:47:18
【问题描述】:

我有一个任务,但我不太确定如何去做。基本上我必须创建一个协调进程来创建 5 个等待被唤醒的工作进程。协调器将标记(整数)传递给第一个进程,然后该进程将标记递增 1 并将其传递给下一个进程。协调进程唤醒下一个执行相同操作的进程,依此类推。所谓的标记应该经过所有过程 10 次,最后它的值应该由协调器打印出来。应使用信号以及标记的共享内存。

所以我创建了 5 个进程,并且我认为在每次迭代中都应该有一个信号,并且应该传递一个处理程序,它基本上可以使用标记完成所有工作。 这是我第一次使用流程。这是我目前所拥有的:

    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <sys/shm.h>
    #include <signal.h>

    #define numOfProcesses 5
    pid_t procIDs[5];
    void handler(int signum){
        //marker and all work here
    }
    void createProcesses(){
        int i;
        for(i = 0; i < numOfProcesses; i++){
            procIDs[i] = fork();
            if(procIDs[i] < 0 ){
                perror("Fork error!");
            }else if(procIDs == 0){
                pause();
            }
        }
    }

    int main(){
        createProcesses();
        int i;
        for(i = 0; i < numOfProcesses; i++){
            pkill(SIGUSR1, handler);
        }

        return 0;
    }

老实说,我不知道该怎么做。我真的很感激你的建议。提前致谢!

【问题讨论】:

    标签: c process signals shared-memory


    【解决方案1】:

    这是我想出的。抱歉回答,我无法找到如何在评论中格式化代码。反正: 每个过程应该是10次。我正在使用共享内存,所以我想我不需要标记的全局变量?这是我想出的:

    #include<stdio.h>
    #include<unistd.h>
    #include<stdlib.h>
    #include<sys/types.h>
    #include<sys/wait.h>
    #include<sys/shm.h>
    #include<signal.h>
    #include<sys/ipc.h>
    
    #define numOfProcesses 5
    #define numOfLoops 10
    
    pid_t* procIDs[5];
    
    void createProcesses(){
        int i;
        for(i = 0; i < numOfProcesses; i++){
            procIDs[i] = fork();
            if(procIDs[i] < 0 ){
                perror("Fork error!");
            }
            else if(procIDs == 0){
                pause();
            }
        }
    }
    
    void init(){//init marker = 0
        key_t mykey = ftok(".", 0);
        int shID = shmget(mykey, sizeof(int), 0666 | IPC_CREAT);
        int *data;
        data = (int*) shmat(shID, 0, 0);
        *data = 0;
    }
    
    int* getValue(){//get value of marker
        key_t mykey = ftok(".", 0);
        int shID = shmget(mykey, sizeof(int), 0666 | IPC_CREAT);
        int *data = shmat(shID, 0, 0);
        return data;
    }
    
    void increment(int sig){//increment + 1
        if(sig == SIGUSR1){
            int temp;
            int* data;
            data = getValue();
            temp = *data;
            temp++;
            *data = temp;
        }
    }
    
    void yourFunc(int count, pid_t* mypid, int mysig){
        if(count == 0){
            return;
        }else{
            printf("Signal sent :: to PID : %d\n", mypid);
            kill(*mypid, SIGUSR1);
            yourFunc(count -1, ++mypid, SIGUSR1);
        }
    }
    
    int main(){
        signal(SIGUSR1, increment);
        init();
        int i,j;
        createProcesses();
    
        for(j = 0; j < numOfLoops; j++){//loop every pid 10 times
            pid_t* currProcess = procIDs[0];
            yourFunc(numOfProcesses, currProcess, SIGUSR1);
        }
        int* data = getValue();
        printf("Marker: %d\n", *data);
        return 0;
    }
    

    【讨论】:

      【解决方案2】:

      我试过你的问题,但我真的对你问题的结构感到困惑,它真的不清楚你的问题陈述是什么。 每次10次(每个进程10次或总共10次(每个进程2次)

      您说进程正在等待被唤醒,这暗示它们不是子进程,而是系统上运行的其他进程,并且需要fifo进行通信。

      尽管如此,我可以从有限的信息中得出以下结论。

      1. 您需要创建一个函数,该函数将由协调器在第一个进程(等待被唤醒)上调用 10 次(循环)

      2. 该函数将递归调用第二个进程,依此类推,直到最后一个休眠进程。

      3. 您必须使用 SIGUSR1,并在自定义信号处理程序中为其定义操作,

      例如。

      signal(SIGUSR1,custom_handler)
      

      您需要将标记保留为全局变量。 因为 C 是一种过程语言,一旦进程终止,内核的调度不在您的手中,您无法回忆它或确保分叉进程的 PID 相同。

      因此,如果您正在考虑在函数内部创建进程,这些进程将被暂停并在收到信号时恢复,好吧.....!,但这将是一次性的。

      您的问题提供的信息有限,我只能说这些。

      以下是 C 中的上述思想。 在调用者中初始化计数 = 5(进程数)。 mypid 指向第一个进程的 PID。

      void party_time(int count, pid_t* mypid, int mysig)
      {
          if(count == 0)
              return;
          else
          {
              printf("Signal sent :: to PID : %d\n",*mypid);
              kill(*mypid,SIGUSR1);
              party_time(count - 1 ,++mypid,SIGUSR1);
          }
      
      }
      

      【讨论】:

      • 每个进程应该是10次。我正在使用共享内存,所以我想我不需要标记的全局变量?这就是我想出的:
      猜你喜欢
      • 1970-01-01
      • 2011-08-18
      • 1970-01-01
      • 2018-10-27
      • 1970-01-01
      • 2021-12-09
      • 1970-01-01
      • 1970-01-01
      • 2013-07-31
      相关资源
      最近更新 更多