我正在用C实现一个派生Web服务器。基本思想是使用fork()
系统调用创建多个工作进程并将它们置于“睡眠”状态,以等待父进程分配工作。问题是我不能使用繁忙的等待来同步进程。我需要像pthread_cond_broadcast
这样的机制可以使子进程进入睡眠状态,以便父进程可以根据需要唤醒它们。
答案 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)
man sem_overview
答案 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条件和互斥锁的事实是我没有正确配置它们。希望这对某人有帮助!