Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 信号量模拟程序:分段错误_C_Linux_Semaphore - Fatal编程技术网

C 信号量模拟程序:分段错误

C 信号量模拟程序:分段错误,c,linux,semaphore,C,Linux,Semaphore,我已经编写了下面的程序,它模拟了信号量的工作。有三个功能:锁定、解锁、锁定路径 锁定=打开文件;检查文件是否已存在,如果已存在,则将当前进程置于休眠状态。如果文件不存在,则创建该文件并返回TRUE 解锁=删除文件 lockpath=返回可能创建的文件对应的路径名 以下是源代码: #include <unistd.h> //exit(); #include <stdlib.h> //errno #include <errno.h> //creat(

我已经编写了下面的程序,它模拟了信号量的工作。有三个功能:锁定、解锁、锁定路径

锁定=打开文件;检查文件是否已存在,如果已存在,则将当前进程置于休眠状态。如果文件不存在,则创建该文件并返回TRUE

解锁=删除文件

lockpath=返回可能创建的文件对应的路径名

以下是源代码:

    #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;
}
#包括
//退出();
#包括
//厄尔诺
#包括
//创建(…)
#包括
#包括
#包括
//strcat,strcpy
#包括
//对于错误系统
#包括
#定义LOCKDIR“/tmp/”
#定义MAXTRY 3
#定义等待时间5
枚举布尔值{TRUE,FALSE};
无效错误系统(常量字符*x){
perror(x);
出口(1);
}
静态字符*锁路径(字符*名称){
静态字符路径[20];
strcpy(路径,LOCKDIR);
返回(strcat(路径、名称));
}
int锁(字符*名称){
字符*路径;
int fd,incerc;
外部内部错误;
路径=锁定路径(名称);
int try=0;
而((fd=open(path,O|u WRONLY | O|u CREAT | O|u EXCL,0666))<0
&&errno==EEXIST){
如果(++try>=MAXTRY)
返回FALSE;
睡眠(等待时间);
}
如果(fd<0 | |闭合(fd)<0)
错误系统(“锁定”);
返回TRUE;
}
无效解锁(字符*名称){
如果(取消链接(锁路径(名称))<0)
错误系统(“解锁”);
}
内部主(空){
pid_t child_进程;
child_进程=fork();
char*sem\u file\u name=“test\u semaf”;
if(子进程!=0)
{
printf(“\n代理进程ID:%d”,getpid());
}
其他的
{ 
printf(“\n归档进程ID:%d”,getpid());
}
if(锁(扫描电镜文件名))
{
printf(“\n ID为%d的进程”,getpid());
printf(“\nonly,有权访问%s”,strcat(LOCKDIR,sem_文件名))//****
解锁(扫描电镜文件名);
}否则{
printf(“\n ID为%d的进程”,getpid());
printf(“\n无法访问%s”,strcat(LOCKDIR,sem_文件名));
}
返回0;
}
程序停止的行标有:****

错误是:

程序接收信号SIGSEGV,分段故障。 __strcat_ssse3()位于../sysdeps/x86_64/multiarch/strcat-ssse3.S:571 571../sysdeps/x86_64/multiarch/strcat-ssse3.S:没有这样的文件或目录

问题是我遇到了分割错误,无法找到问题所在。对我来说,一切都很好。一个进程应该创建文件X。然后,如果另一个进程试图创建它自己的文件X,那么它是不允许的;这一过程进入休眠状态。允许第二个进程进行最大尝试。如果在MAXTRY尝试后没有成功,lock()函数将返回FALSE。最后,当成功创建了自己的X文件的进程现在不需要它时,文件X将被删除

你能告诉我你认为这个计划有什么问题吗?先谢谢你


编辑: 下面是指向页面的链接,解释了lockpath()函数不正确的原因


这是导致您的崩溃的原因:

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缓冲区,并将其作为参数传递给它。

在调试器中运行,然后它将捕获实际发生的崩溃,并让您找到它发生的位置。如果它不在你的代码中,那么你沿着调用堆栈走,直到你找到你的代码。在那里,您可以检查所有相关变量的值,并有望看到导致崩溃的原因。至少,请编辑您的问题以包括崩溃的位置,就像在源代码中添加注释一样。顺便问一下,您确定代码可以编译吗?例如,在
lock
函数中,您使用了一个变量
try
,但您似乎没有在任何地方定义它?此外,在构建程序时,您可能应该启用更多警告,例如添加
-Wall-Wextra-pedantic
编译器标志。@JoachimPileborg我已经运行了调试器,并得到了错误。似乎找不到某个文件。然而,这很奇怪。谢谢你。现在我明白问题所在了。