当我运行此代码时,请任何人帮助我 我得到分段错误(核心转储) 这是一个gaz站问题的程序我想同步来到车站的汽车类型和我使用共享的mameory并保存一些变量同步但是当我运行程序时显示我的分段故障我在fedora 13中运行它 `
//tmp* global=null;
int i=1;
//define struct for save it shared memory segment
typedef struct{
int emergen ;
int truck ;
int type;
char car[20];
int gaz;
int pid;
}tmp;
tmp * global;
//emergency car handler
void emergency(int sig);
//handler of truck and normal car
void normal(int sig);
void main()
{
printf("hello I'm gaz station");
tmp* shared_memory;
key_t k = ftok("/tmp",'a');
//allocate shared memory
const int shared_segment_size = 0x6400;
//allocate shared memory
int seg_id=shmget(k,shared_segment_size,IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR | S_IROTH | S_IWOTH );
//attach to shared memory
shared_memory = (tmp*) shmat (seg_id, 0, 0);
//write to shared memory
//memccpy(shared_memory,&tmp,sizeof(tmp));
//some vars i used as semaphore for syncronize other process
global=shared_memory;
global->emergen=1;
global->truck=1;
global->pid=getpid();
//define mask for signal handler
sigset_t newsigset;
sigemptyset(&newsigset);
sigfillset(&newsigset);
sigdelset(&newsigset,SIGINT);
sigdelset(&newsigset,SIGUSR1);
sigdelset(&newsigset,SIGQUIT);
//handle the signals
if(sigprocmask(SIG_BLOCK,&newsigset,NULL)<0)
{
printf("ann error in sigprocmask \n");
}
//sigactiion function
struct sigaction act;
sigemptyset(&act.sa_mask);
sigfillset(&act.sa_mask);
act.sa_handler=emergency;
if(sigaction(SIGINT,&act,NULL))
{
printf("couldn't execute sigaction for SIGINT signal \n");
}
//sigaction for SIGQUIT SIGUSR1
struct sigaction act1;//define struct for sigaction
act1.sa_handler=normal;
act1.sa_flags=SA_NODEFER;
sigemptyset(&act1.sa_mask);
if(sigaction(SIGUSR1,&act1,NULL)==-1)
{
printf("error in sigaction for SIGUSR1 SIGUSR1 \n");
}
if(sigaction(SIGQUIT,&act1,NULL)==-1)
{
printf("error in sigaction for SIGQUIT SIGUSR1 \n");
}
while(1)
;
}
//handler for type of car
void emergency(int sig)
{
printf("*****************************************\n");
printf("i'm emergency car ...... and my name %s",global->car);
//char[20] name;
//printf("please enter the name of the car \n");
//scanf("%s \n",name);
//strcpy(global.car,name);
sleep(1.5);
printf("emergency car that called %s finish",global->car);//print for user
printf("%d remain in the station \n",global->gaz);
printf("*****************************************\n");
}
//handler of truck and normal car
void normal(int sig)
{
if(i!=1)
{printf("interrupt has been occured \n");}
printf("*****************************************\n");
i=0;
if(sig==SIGUSR1)
{
printf("I'm truck \n");
printf("my name is %s \n",global->car);
sleep(1.5);
//type of car that come to gaz station
if(global->type==1)
{
printf("truck %s finish support the station \n",global->car);
//printf("*****************************************\n");
}
else if(global->type==2)
{
printf("truck %s finish the process \n",global->car);
}
sleep(1.5);
printf("%d remain in the station \n",global->gaz);
printf("*****************************************\n");
}
else if(sig==SIGQUIT)
{
printf("I'm normal car my name is %s \n",global->car);
sleep(1.5);
printf("car finish \n");
printf("*****************************************\n");
}
i=1;
} `
答案 0 :(得分:0)
使用信号比它的声音复杂得多,因此你应该只将它们用于它们的目的:捕获一个事件(通常是一个系统事件)并尽可能地做一些事情,比如通过写一个字节来解锁一个消费者线程打开的管道或使用sem_post
。
程序的正常执行在信号的任何地方都会中断。
当您在信号中调用printf
时,用于根据给定参数构建字符串的printf
内部静态变量会被更改。
如果在发出信号时,程序的正常执行位于printf
调用内,则信号陷阱会破坏内部静态变量,printf
调用将无法恢复。这同样适用于许多标准函数,例如strerror
。
This opengroup link为您提供信号陷阱中已接受的标准函数调用的详尽列表。你可以看到不应该使用printf
(奇怪的是sleep
可以)。
但是,由于程序的正常执行是一个简单的空循环, 这不应该是我猜的问题。但是您的全局变量很有意义:
car
数组可能不包含任何\0
)如果在完全初始化此global
变量之前调用了陷阱,
或者当另一个过程正在改变它时,那么你的程序可能会行为不端。如果其他进程正在使用共享的global
变量,而此变量正在改变它,则同样适用。共享内存访问应始终使用系统互斥或原子更新进行保护,但从信号陷阱(sem_wait
调用)内部获取互斥锁是不行的。因此,你的程序设计对我来说是错误的。