我正在编写一个使用进程间消息队列的 C 程序。我正在尝试重现进程 J(法官)和 n 个子进程之间的拍卖。程序从输入文件 txt 和一些子进程中获取。
这是我的代码:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/wait.h>
#include <time.h>
#include <ctype.h>
#define MSG_SIZE sizeof(msg)-sizeof(long)
#define BUFFER 1024
typedef struct{
long type;
char id;
int min_offerta;
int max_offerta;
long bindders_offert;
char object[BUFFER];
char done;
long num_aste;
char counter_done;
}msg;
void bidders(int id,int coda,int num_bidders){
srand(time(NULL));
msg messaggio;
int wait;
long offerta;
while(1)
{
if((msgrcv(coda,&messaggio,MSG_SIZE,0,0))==-1)
{
perror("msgrcv");
exit(1);
}
if(messaggio.done){
messaggio.counter_done++;
break;
}
wait=rand()%3;
printf("[B%d]: attendo per %d secondi\n",id,wait);
sleep(wait);
offerta=(rand()% messaggio.max_offerta);
messaggio.bindders_offert=offerta;
messaggio.id=id;
if((msgsnd(coda,&messaggio,MSG_SIZE,0))==-1)
{
perror("msgsnd");
exit(1);
}
printf("[B%d] invio offerta di %d per asta n.%d per %s\n",id,offerta,messaggio.num_aste,messaggio.object);
}
if(messaggio.counter_done==num_bidders)
{
msgctl(coda,IPC_RMID,NULL);
}
exit(0);
}
int main(int argc, char* argv[]){
int coda;
if(argc<3)
{
fprintf(stderr,"Utilizzo: %d <action-file> <num-bidders>\n",argv[0]);
exit(1);
}
if((coda=msgget(IPC_PRIVATE,IPC_CREAT|0600))==-1)
{
perror("msgget");
exit(1);
}
int num_bidders=atoi(argv[2]);
for(int i=0; i<num_bidders; i++)
{
if(!fork())
bidders(i+1,coda,num_bidders);
}
FILE* file;
char tmp[BUFFER];
msg messaggio;
long num_aste=0,aste_concluse=0,aste_nulle=0;
char* path=argv[1], *min_offerta, *max_offerta,* object;
int max=0,min=0;
if((file=fopen(path,"r"))==NULL)
{
perror("fopen");
exit(1);
}
while(fgets(tmp,BUFFER,file))
{
if(tmp[strlen(tmp)-1]=='\n')
tmp[strlen(tmp)-1]='\0';
num_aste++;
messaggio.type=1;
messaggio.done=0;
messaggio.num_aste=num_aste;
if((object=strtok(tmp,","))!=NULL)
{
if((min_offerta=strtok(NULL,","))!=NULL)
{
if((max_offerta=strtok(NULL,","))!=NULL)
{
max=atoi(max_offerta);
min=atoi(min_offerta);
strncpy(messaggio.object,object,BUFFER);
}
}
}
messaggio.max_offerta=max;
messaggio.min_offerta=min;
printf("[J] lancio asta n.%ld per %s con offerta minima di %d e massima di %d\n",num_aste,messaggio.object,messaggio.min_offerta,messaggio.max_offerta);
if((msgsnd(coda,&messaggio,MSG_SIZE,0))==-1)
{
perror("msgsnd");
exit(1);
}
if((msgrcv(coda,&messaggio,MSG_SIZE,0,0))==-1)
{
perror("msgrcv");
exit(1);
}
printf("[J] ricevo offerta di %ld da %d\n",messaggio.bindders_offert,messaggio.id);
}
printf("[J]Exit\n");
messaggio.type=1;
messaggio.done=1;
if((msgsnd(coda,&messaggio,MSG_SIZE,0))==-1)
{
perror("msgsnd");
exit(1);
}
printf("Sono state svolte n.%ld aste!\n",num_aste);
}
输出应该是这样的:
J: lancio asta n.1 per Cotta di Mithril con offerta minima di 100 EUR e massima di 500 EUR
B2: aspetto per 0 secondi
B2: invio offerta di 334 EUR per asta n.1 per Cotta di Mithril
J: ricevuta offerta da B2
B1: aspetto per 1 secondi
B1: invio offerta di 221 EUR per asta n.1 per Cotta di Mithril
J: ricevuta offerta da B1
J: lancio asta n.2 per Palantìr con offerta minima di 700 EUR e massima di 1000 EUR
B4: aspetto per 3 secondi
B2: invio offerta di 409 EUR per asta n.2 per Palantìr
J: ricevuta offerta da B2
B4: aspetto per 0 secondi
B1: invio offerta di 99 EUR per asta n.2 per Palantìr
J: ricevuta offerta da B1
B4: aspetto per 3 secondi
B4: invio offerta di 598 EUR per asta n.2 per Palantìr
J: ricevuta offerta da B4
B3: aspetto per 2 secondi
B3: invio offerta di 650 EUR per asta n.2 per Palantìr
J: ricevuta offerta da B3
J:Exit
Sono state svolte n.2 aste!
但我的输出是:
[J] lancio asta n.1 per Cotta di Mithril con offerta minima di 100 e massima di 500
[B1]: attendo per 2 secondi
[B1] invio offerta di 72 per asta n.1 per Cotta di Mithril
[B2]: attendo per 2 secondi
[B2] invio offerta di 72 per asta n.1 per Cotta di Mithril
[J] ricevo offerta di 72 da 2
[J] lancio asta n.2 per Palantír con offerta minima di 700 e massima di 1000
[B1]: attendo per 2 secondi
[B1] invio offerta di 281 per asta n.2 per Palantír
[B2]: attendo per 2 secondi
[B2] invio offerta di 281 per asta n.2 per Palantír
[J] ricevo offerta di 281 da 2
[J]Exit
Sono state svolte n.2 aste!
为什么进程J只拿到最后的offer?为什么我不能在两个进程之间生成不同的随机暂停?我哪里做错了?