如何解决分叉 3 次,试图始终如一地输出在循环中递增的值
目标是让输出从 1 开始并达到 150,目前只有 1 到 60,并且有多个重复。我想保持 main 不变,只使用信号量来处理 process() 函数。这是我对如何使用post和wait的解释。如果这是错误的,请告诉我。
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <fcntl.h>
#include <sys/stat.h>
// //dev/shm/sem.X <- unlinks
sem_t *sem;
/*
sem = sem_open("X",O_CREAT | O_EXCL,0777,N);
sem_unlink("X");
sem_getvalue(sem,&N);
sem_post(sem);
*/
void process(){
int ret;
int N = 1;
int a;
sem = sem_open("X",1);
sem_unlink("X");
for(int i = 0; i< 50; i++){
sem_wait(sem);
FILE* infile = fopen ("infile.txt","r");
fscanf (infile,"%d",&N);
fclose (infile);
N++;
printf("N: %d Process ID: %d \n",N,getpid());
infile = fopen("infile.txt","w");
fprintf(infile,N);
fclose(infile);
sem_post(sem);
}
exit(0);
}
int main(){
FILE *fp = fopen("infile.txt","w");
fprintf(fp,1);
fclose(fp);
int pid,pid1,pid2;
pid = fork();
if(pid == 0){
//child1,Last
printf("Starting Process C: \n");
process();
}
else{
pid1 = fork();
if(pid1 == 0){
//child2,Middle
printf("Starting Process B: \n");
process();
}
else{
pid2 = fork();
if(pid2 == 0){
//child 3,First
printf("Starting Process A: \n");
process();
}
else{
}
}
}
//sem_close(&X);
}
解决方法
在 sem_open
中执行 process
后跟 sem_unlink
是不正确的。
每个进程将获得一个不同信号量,因此它们将不协调。
将 sem_open
移至 main
并删除 sem_unlink
。然后,所有进程将使用相同/正确的信号量。
请注意,主/主进程不执行 wait
[并立即终止],因此子进程附加到 init 进程。更好的做法:while (wait(NULL) >= 0);
在 main
我们需要在sem_close
的底部做sem_unlink
然后main
这是一些重构的代码。注释:
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/wait.h>
// //dev/shm/sem.X <- unlinks
sem_t *sem;
#if 0
sem = sem_open("X",O_CREAT | O_EXCL,0777,N);
sem_unlink("X");
sem_getvalue(sem,&N);
sem_post(sem);
#endif
void
process()
{
int ret;
int N = 1;
int a;
// NOTE/BUG: by doing this here each process gets it's own semaphore so nothing
// will be coordinated
#if 0
sem = sem_open("X",1);
sem_unlink("X");
#endif
for (int i = 0; i < 50; i++) {
sem_wait(sem);
FILE *infile = fopen("infile.txt","r");
fscanf(infile,"%d",&N);
fclose(infile);
N++;
printf("N: %d Process ID: %d \n",N,getpid());
infile = fopen("infile.txt","w");
fprintf(infile,N);
fclose(infile);
sem_post(sem);
}
exit(0);
}
int
main()
{
FILE *fp = fopen("infile.txt","w");
fprintf(fp,1);
fclose(fp);
// NOTE/FIX: one semaphore for all processes
#if 1
sem = sem_open("X",1);
//sem_unlink("X");
#endif
int pid,pid1,pid2;
pid = fork();
if (pid == 0) {
// child1,Last
printf("Starting Process C: \n");
process();
}
else {
pid1 = fork();
if (pid1 == 0) {
// child2,Middle
printf("Starting Process B: \n");
process();
}
else {
pid2 = fork();
if (pid2 == 0) {
// child 3,First
printf("Starting Process A: \n");
process();
}
else {
}
}
}
// sem_close(&X);
// NOTE/FIX: wait for all subprocesses to finish
#if 1
while (1) {
pid = wait(NULL);
if (pid < 0)
break;
}
#endif
// NOTE/FIX: we must close and unlink so that we can be invoked again
#if 1
sem_close(sem);
sem_unlink("X");
#endif
return 0;
}
上述方法有效,但我会使用循环来启动三个进程,而不是嵌套的 if/else
语句。如果我们必须创建 1000 个进程,这个解决方案会更明显:
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/wait.h>
// //dev/shm/sem.X <- unlinks
sem_t *sem;
#if 0
sem = sem_open("X",1);
//sem_unlink("X");
#endif
pid_t pid;
for (int count = 1; count <= 3; ++count) {
pid = fork();
if (pid == 0)
process();
}
// NOTE/FIX: wait for all subprocesses to finish
#if 1
while (1) {
pid = wait(NULL);
if (pid < 0)
break;
}
#endif
// NOTE/FIX: we must close and unlink so that we can be invoked again
#if 1
sem_close(sem);
sem_unlink("X");
#endif
return 0;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。