下面的这段代码,在linux 编译成功后,执行的时候,有时会出现一个问题:
就是第一个闹钟很成功的捕捉到,担是第二个闹钟却挂我程序。
这种情况,有时一出现就一直出现,但有时就不出现了。
是哪个地方有隐患啊?
小弟水平也就这样了,还忘大神指点一二。
/* process_svr.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/time.h>
#include <signal.h>
#include <errno.h>
#define NONE "\033[m"
#define RED "\033[0;32;31m"
#define LIGHT_RED "\033[1;31m"
#define GREEN "\033[0;32;32m"
#define LIGHT_GREEN "\033[1;32m"
#define BLUE "\033[0;32;34m"
#define LIGHT_BLUE "\033[1;34m"
#define DARY_GRAY "\033[1;30m"
#define CYAN "\033[0;36m"
#define LIGHT_CYAN "\033[1;36m"
#define PURPLE "\033[0;35m"
#define LIGHT_PURPLE "\033[1;35m"
#define BROWN "\033[0;33m"
#define YELLOW "\033[1;33m"
#define LIGHT_GRAY "\033[0;37m"
#define WHITE "\033[1;37m"
void alrm_func(int sn);
void int_func(int sn);
pthread_mutex_t *p_mutex_shared = NULL;
int shmid = -1;
int main(int argc, char *argv[])
{
// 创建一个共享内存段
key_t key_id = ftok(".", 1);
shmid = shmget(key_id, sizeof(pthread_mutex_t),
IPC_CREAT | IPC_EXCL | 0644);
if (shmid < 0)
{
perror(RED "shmget() create failed" NONE);
return -1;
}
printf("shmget() create success, shmid is %d.\n", shmid);
// 挂接到共享内存
p_mutex_shared = shmat(shmid, NULL, 0);
if (p_mutex_shared == (void *)-1)
{
perror(RED "shmat() failed" NONE);
// 删除共享内存,这里实际只是标记为删除,真正的删除动作在所有挂接的进程都
// 脱接的状态下进行。
// 同时不允许有新进程挂接到该共享内存上。
shmctl(shmid, IPC_RMID, 0);
return -2;
}
printf("shmat() success.\n");
// 初始化共享内存段,存放互斥锁,该锁用于不同进程之间的线程互斥。
pthread_mutexattr_t mutextattr;
pthread_mutexattr_init(&mutextattr);
// 设置互斥锁在进程之间共享
pthread_mutexattr_setpshared(&mutextattr, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(p_mutex_shared, &mutextattr);
signal(SIGALRM, alrm_func);
signal(SIGINT, int_func);
struct itimerval itimer = { {0, 500000}, {0, 5000} };
setitimer(ITIMER_REAL, &itimer, NULL);
while (1)
sleep(1);
return 0;
}
void alrm_func(int sn)
{
if (p_mutex_shared == NULL)
{
printf("p_mutex_shared is NULL.\n");
return ;
}
time_t tm = time(NULL);
printf("%s\t", ctime(&tm));
if (pthread_mutex_trylock(p_mutex_shared) == 0)
{
printf(GREEN "pthread_mutex_trylock success.\n" NONE);
pthread_mutex_unlock(p_mutex_shared);
}
else
{
printf(BLUE "pthread_mutex_trylock failed.\n" NONE);
}
printf("################################################\n");
}
void int_func(int sn)
{
if (p_mutex_shared != NULL)
{
// 脱接
if (shmdt(p_mutex_shared) == -1)
perror(RED "shmdt() failed" NONE);
else
printf("shmdt() success.\n");
p_mutex_shared = NULL;
}
if (shmid != -1)
{
// 删除共享内存
if (shmctl(shmid, IPC_RMID, NULL) == -1)
perror(RED "shmctl() IPC_RMID is failed" NONE);
else
printf("shmctl() IPC_RMID is success.\n");
shmid = -1;
}
exit(0);
}
有两种解决办法:
1、把signal换成sigaction方式注册信号处理函数。
2、在alrm_func函数里面再次用signal注册信号处理函数
建议安装libc6-gbg,这样在gdb当中可知道你挂在了那个函数内部
sudo apt-get install libc6-dbg
当你的程序挂住的时候按下C-\生成core文件,然后在gdb当中查看堆栈,立刻可看出你问题的根源。
gdb ./a.out core
bt