以下のコードを書きましたが、次のものが必要です。
5 秒ごとに、親はランダムな int を取得して共有メモリに入れ、子にシグナルを送信します。
子は、その量の乗客を運ぶために必要なトラムの数を計算し (TRAM_CAP などの定義があることがわかります)、新しいトラムの数を共有メモリに入れます。
最後に、シグナルによって通知された後、親は乗客とトラムの数を出力します。
私の問題は、信号が送信されないことですが、その理由はわかりません。
何百万回も検索してグーグルで検索しましたが、何もありません...タイマーは機能していますが、他には何もありません(最初の「路面電車の量の計算」だけです)
ところで、これは私が人生で書いた2番目のCコードです:Sだから私は初心者です。
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "fcntl.h"
#include "errno.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "unistd.h"
#include <sys/time.h>
#include <signal.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <math.h>
#define MEM_KEY 2003
#define INTERVAL 2
#define NEW_STAT SIGUSR1
#define NEW_TRAM_CNT SIGUSR2
#define MAX_PASSENGER 1000
#define TRAM_CAP 60
// "slots" in shared memory
#define PASS_CNT 0
#define TRAM_CNT 1
int get_pass_stat();
void handle_pass_stat_generation (int sig);
void handle_exit_func (int sig);
void set_pass_stat_generation();
void handle_new_tram_cnt_set(int sig);
void handle_new_stat_arrived(int sig);
void set_data(int which, int to);
int get_data(int which);
static pid_t ppid;
static pid_t chpid;
int main()
{
int shmid = shmget((key_t) MEM_KEY, sizeof(int) * 2, IPC_CREAT | 0666);
int* segptr = shmat(shmid, 0, 0);
segptr[PASS_CNT] = 0;
segptr[TRAM_CNT] = 0;
// seed for rand
srand((unsigned)time(NULL));
//
int pid=fork();
if(pid == 0) // child
{
signal(NEW_STAT, handle_new_stat_arrived);
while(1) sleep(30);
}else if(pid > 0) // parent
{
chpid = pid;
ppid = getpid();
signal(NEW_TRAM_CNT, handle_new_tram_cnt_set);
signal(SIGINT,handle_exit_func);
set_pass_stat_generation(pid);
while(1) sleep(30);
}else
{
perror("Fork error.");
exit(1);
};
return 0;
}
int get_pass_stat()
{
return rand() % MAX_PASSENGER + 1;
}
void handle_pass_stat_generation (int sig)
{
int st = get_pass_stat();
set_data(PASS_CNT, st);
kill( chpid, NEW_STAT );
printf("%i is the pass. cnt %i is the tram cnt. \n", st, get_data(TRAM_CNT));
// set_pass_stat_generation();
}
void handle_exit_func (int sig)
{
printf("\nBye Bye!!!\n");
exit(0);
}
void set_pass_stat_generation()
{
struct itimerval tval;
tval.it_interval.tv_sec = INTERVAL;
tval.it_interval.tv_usec = 0;
tval.it_value.tv_sec = INTERVAL; /* 5 seconds timer */
tval.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &tval,0);
signal(SIGALRM, handle_pass_stat_generation); /* set the Alarm signal capture */
}
void handle_new_stat_arrived(int sig)
{
int tram_count = get_data(TRAM_CNT);
int passenger_count = get_data(PASS_CNT);
if( (TRAM_CAP * tram_count < passenger_count) ||
(TRAM_CAP * (tram_count-1) > passenger_count) ||
(passenger_count == 0) )
{
int new_cnt = (int) ceil((double)passenger_count / (double)TRAM_CAP);
set_data(TRAM_CNT, new_cnt);
kill( ppid, NEW_TRAM_CNT );
}
signal(NEW_STAT, handle_new_stat_arrived);
}
void handle_new_tram_cnt_set(int sig)
{
signal(NEW_TRAM_CNT,handle_new_tram_cnt_set);
}
void set_data(int which, int to)
{
int shmid = shmget((key_t) MEM_KEY, 0, 0);
int* segptr = shmat(shmid, 0, 0);
segptr[which] = to;
}
int get_data(int which)
{
int shmid = shmget((key_t) MEM_KEY, 0, 0);
int* segptr = shmat(shmid, 0, 0);
return segptr[which];
}