我写了下面的程序,模拟信号量的工作。 有三个function:locking,解锁,lockingpath。
lock =打开文件; 检查文件是否已经存在,如果存在,则将当前进程置于睡眠状态。 如果文件不存在,则创build并返回TRUE。
解锁 =删除文件
lockpath =返回可能创build的文件对应的path名。
以下是源代码:
#include <unistd.h> //exit(); #include <stdlib.h> //errno #include <errno.h> //creat(..) #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> //strcat, strcpy #include <string.h> //For err_sys #include <stdio.h> #define LOCKDIR "/tmp/" #define MAXTRY 3 #define WAITTIME 5 enum BOOLEAN{TRUE, FALSE}; void err_sys(const char* x) { perror(x); exit(1); } static char* lockpath(char* name) { static char path[20]; strcpy(path, LOCKDIR); return (strcat(path, name)); } int lock(char* name) { char *path; int fd, incerc; extern int errno; path = lockpath(name); int try = 0; while ((fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0666)) < 0 && errno == EEXIST) { if (++try >= MAXTRY) return FALSE; sleep(WAITTIME); } if (fd < 0 || close(fd) < 0) err_sys("lock"); return TRUE; } void unlock(char* name) { if (unlink(lockpath(name)) < 0) err_sys("unlock"); } int main(void) { pid_t child_process; child_process = fork(); char* sem_file_name = "test_semaf"; if (child_process != 0) { printf("\nParent process ID: %d", getpid()); } else { printf("\nChild process ID: %d", getpid()); } if (lock(sem_file_name)) { printf("\nProcess with ID: %d", getpid()); printf("\nonly, has access to %s", strcat(LOCKDIR, sem_file_name)); //**** unlock(sem_file_name); } else { printf("\nProcess with ID: %d", getpid()); printf("\nwas unable to get access to %s", strcat(LOCKDIR, sem_file_name)); } return 0; }
程序停止的行标有:****
错误是:
程序收到信号SIGSEGV,分段故障。 __strcat_ssse3()at ../sysdeps/x86_64/multiarch/strcat-ssse3.S:571 571 ../sysdeps/x86_64/multiarch/strcat-ssse3.S:没有这样的文件或目录。
问题是,我得到分段错误,并找不到问题的地方。 对我来说,一切都很好。 一个进程应该创build文件X.然后,如果另一个进程试图创build它自己的文件X,这是不允许的; 这个过程是睡着了。 允许第二个进程进行MAXTRY尝试。 如果它在MAXTRY尝试后没有成功,则lock()函数返回FALSE。 最后,当一个已经成功创build自己的X文件的进程现在不需要它时,文件X被删除。
你能告诉你这个程序有什么问题吗? 先谢谢你。
编辑:这是解释为什么lockpath()函数不正确的页面的链接。
返回一个指向静态局部variables安全的指针?
这是你的崩溃的原因:
strcat(LOCKDIR, sem_file_name)
在这里你尝试附加到一个文字字符串常量。
你也应该在这里使用lockpath函数。
这个问题似乎是你对strcat()函数的误解。 该函数将第二个参数中的字符串附加到第一个参数中的字符串 – 但是您需要确保数据有足够的空间 。 阅读手册页 。
这意味着
char * dest = "whatever"; strcat(dest, anything_else);
总是错的 你想要的是
char dest[SIZE] = "whatever"; strcat(dest, anything_else);
其中SIZE足够大,缓冲区能够包含整个连接的字符串。
此外,您的lockpath()函数已损坏。 看到这个答案 ,了解为什么。 您需要在lockpath()函数之外创建dest缓冲区,并将其作为参数传递给它。