C中的进程同步,无需等待

时间:2020-04-25 22:07:39

标签: c fork

我正在用C实现一个派生Web服务器。基本思想是使用fork()系统调用创建多个工作进程并将它们置于“睡眠”状态,以等待父进程分配工作。问题是我不能使用繁忙的等待来同步进程。我需要像pthread_cond_broadcast这样的机制可以使子进程进入睡眠状态,以便父进程可以根据需要唤醒它们。

4 个答案:

答案 0 :(得分:0)

如果必须使用fork()而不是pthreads,则可以使用shm_open(另请参阅similar question)和{{3}在UNIX中的进程之间映射内存}。

我会这样用mmap做到这一点:

#include <stdio.h>
#include <unistd.h>

int main(){
  void *shared_mem=mmap(NULL,NUM_BYTES,PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS,-1,0);
  if(fork()){
    accessMem(shared_mem);
  }
  else{
    accessMem(shared_mem);
  }
}

基本上,您的想法是将内存区域标记为进程之间共享,然后在派生之后,该特定内存区域在两个进程之间保持不变。

祝你好运

答案 1 :(得分:0)

Jim Rogers mentioned in a comment一样,您可以使子进程在读取管道时处于阻塞状态,直到您有工作要做。这是一个如何通过单个子进程执行此操作的示例:

#include <stdio.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

int childmain(int fd) {
    char c;
    if(read(fd, &c, 1) != 1) {
        perror("read");
        return 1;
    }
    printf("Hello from the child process! The parent just woke me up.\n");
    return 0;
}

int main(void) {
    int fds[2];
    if(pipe(fds)) {
        perror("pipe");
        return 1;
    }
    pid_t pid = fork();
    if(pid < 0) {
        perror("fork");
        return 1;
    } else if(pid == 0) {
        if(close(fds[1])) {
            perror("close");
            return 1;
        }
        return childmain(fds[0]);
    }
    if(close(fds[0])) {
        perror("close");
        goto out;
    }
    printf("Child is waiting. Hit Enter to wake it up.\n");
    getchar();
    if(write(fds[1], "", 1) != 1) {
        perror("write");
        goto out;
    }
    printf("Child sent wakeup signal. Now waiting for it to exit...\n");
  out:
    if(wait(NULL) != pid) {
        perror("wait");
        return 1;
    }
    return 0;
}

答案 2 :(得分:0)

您可以在POSIX系统上使用多种同步机制(我假设您拥有叉子就拥有POSIX)

    可以使用
  • 管道(已命名或未命名)-写入和读取“令牌”以进行同步
  • 可通过sem_open获得SYSV信号量对象-请参见man sem_overview
  • sigwait和信号可以使用
  • 套接字(通过套接字对或连接)的用法类似于管道。

答案 3 :(得分:0)

我最终使用了pthread条件和互斥数据类型,我不得不将它们配置为共享对象(在共享内存上创建它们并配置它们的属性)。初始化的示例代码。

用于初始化pthread_mutexattr_t的代码:

pthread_mutexattr_t get_mutex_attributes() {
    pthread_mutexattr_t mattr;
    pthread_mutexattr_init(&mattr);
    // Attribute to allow the mutex to be shared between processes
    pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);
    return mattr;
}

此函数创建属性以将互斥锁初始化为PTHREAD_PROCESS_SHARED,从而允许多个进程使用该锁

然后,使用此功能创建共享内存:

void *create_shared_memory(size_t size) {
    int protection = PROT_READ | PROT_WRITE;
    int flags = MAP_SHARED | MAP_ANONYMOUS | MAP_SYNC;

    return mmap(NULL, size, protection, flags, -1, 0);
}

并初始化互斥锁:

mut_allt = (pthread_mutex_t *) create_shared_memory(sizeof(pthread_mutex_t));
pthread_mutex_init(mut_allt, &mattr);

利用所有这些和一些条件互斥锁,我设法使进程同步,导致我之前无法使用pthread条件和互斥锁的事实是我没有正确配置它们。希望这对某人有帮助!

相关问题