【问题标题】:Make fork execute equal amounts of times, infinitely使 fork 执行相同的次数,无限次
【发布时间】:2019-10-22 04:10:01
【问题描述】:

我试图使以下代码永远不允许 + 的数量大于 - 的数量。我正在考虑添加一个简单的c sleep(1) 行,但我很想知道是否有更好的方法来使数量相等。这应该是一个无限循环。

int main(){
 if(fork() ==0)
    while(1){
       write(1,"-",1)
   }

  else
     while(1){

       write(1, "+",1);
   }

return 0;
}

这个函数使用信号量是否正确?

int main(){

int parent_sem = get_semaphore(0);
int child_sem = get_semaphore(1);

 if(fork() ==0)
    while(1){
        sem_wait(child_sem);
       write(1,"-",1);
       sem_signal(parent_sem);
   }

  else
     while(1){
       sem_wait(parent_sem);
       write(1, "+",1);
       sem_signal(child_sem);
   }

return 0;
}

【问题讨论】:

  • 你想要 IPC。你可以例如使用信号量让他们轮流写一个字符,但是 Linux 有很多选择,所以可能有更好的方法。
  • 是的,它会比那个更复杂,哈哈。你需要同步你的进程,因为它们需要知道彼此的状态。
  • 使用信号量的例子是什么?

标签: c unix ipc


【解决方案1】:

这是您的信号量示例的固定版本。我已经分配了共享内存,以便两个进程都可以通过 fork 访问信号量(我忘了这是必要的,抱歉)并修复了信号量类型和调用。

#include <unistd.h>
#include <semaphore.h>
#include <sys/mman.h>

int main() {
    // Create shared memory for two semaphores
    sem_t* sem = mmap(NULL, 2 * sizeof(sem_t), PROT_READ | PROT_WRITE,
                      MAP_SHARED | MAP_ANONYMOUS, -1, 0);

    // Initialise parent and child semaphores: parent = 1, child = 0
    sem_t* parent_sem = sem;
    sem_t* child_sem = sem + 1;    
    sem_init(parent_sem, 1, 1);
    sem_init(child_sem, 1, 0);

    if (fork() == 0) {
        while(1) {
            // Child process
            sem_wait(child_sem);
            write(1, "-", 1);
            sem_post(parent_sem);
        }
    } else {
        while(1) {
            // Parent process
            sem_wait(parent_sem);
            write(1, "+", 1);
            sem_post(child_sem);
        }
    }

    return 0;
}

【讨论】:

    【解决方案2】:

    这很接近(使用信号):

    #include <unistd.h>
    #include <stdio.h>
    #include <signal.h>
    
    void usr1handler() {
    }
    
    int main(void) {
            int pid;
    
            signal(SIGUSR1, usr1handler);
    
            if ((pid = fork()) == 0) {
                    while (1) {
                            pause();
                            write(1, "-", 1);
                            fflush(stdout);
                            kill(getppid(), SIGUSR1);
                    }
            }
            else {
    
                    sleep(1);
    
                    while (1) {
                            write(1, "+", 1);
                            fflush(stdout);
                            kill(pid, SIGUSR1);
                            pause();
                    }
            }
    
    }
    

    主要问题是竞争条件。如果一个进程在另一个进程到达 pause() 之前到达 kill() 函数,则程序将冻结。这可能足以让你开始。我在那里留下了一个睡眠,所以你可以看到它确实打印均匀。

    【讨论】:

    • 为什么要混合文件描述符 (write) 和 stdio 句柄 (fflush(stdout))?
    猜你喜欢
    • 1970-01-01
    • 2014-03-01
    • 1970-01-01
    • 2019-07-13
    • 1970-01-01
    • 1970-01-01
    • 2016-06-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多