gpt4 book ai didi

C Unix Xcode 再次出现错误

转载 作者:太空宇宙 更新时间:2023-11-04 08:32:04 25 4
gpt4 key购买 nike

我在做一个大学项目,我们要用到Unix系统调用。现在,我真的很难理解在我的项目中是否真的存在错误。这是因为,虽然在终端中它编译并且开始和结束时没有错误,但在 xcode 上我遇到了几个错误。

特别是,我在使用信号量时遇到错误。

我会尝试解释我收到的错误,但由于我的母语不是英语,如果我犯了一些错误,请提前原谅我。

首先,程序用fork()创建了一些子进程。它取决于有多少 clientei.txt 位于(i = 迭代器)。我立即用信号量阻止父级,让子级运行到某个点,然后用信号量阻止它并重新启动父级。

此时,父进程应该读取儿子发送的消息,调用函数打印log.txt中的内容并重启子进程。

然后 child 做其他事情(包括删除消息)并阻止。父进程重新启动,并为后续子进程重复一切。

虽然在终端同步是完美的(一切都在正确的时间发生而没有错误)这对于 Linux 和 Mac,关于 XCode 我有几个错误:

semop:资源暂时不可用(如果我创建了超过5个txt)semop:文件太大(如果我创建了 2 个以上)

with 2 相反给了我两个错误:semop 1:中断的系统调用(这在运行两个进程后停止)semop 3:标识符已删除(在重新启动第二个过程时使用此)

我做C的时间不多了,不知道该干什么。我想首先知道我是否需要担心(所以有错误),或者我必须保持安静,因为它是 xcode 中的一个错误。如果有错误,我恳请您不要要求我大量更改代码。这主要是因为它们快要过期了,我负担不起再做一遍。如果可以的话,我还请您尽可能清楚。我懂足够的英语,但不是母语,我不能总是关注 StackOverflow 上的回复。

代码在这里: https://www.dropbox.com/s/2utsb6r5d7kzzqj/xcode%2Bterminal.zip?dl=0这个 zip 包含有这个问题的项目的一小部分。终端版本有效。这个版本有一个makefile来简化编译。xcode 版本不起作用。它包含调试文件夹。确实是 xcode,txt 文件,它不会从根文件夹中读取代码所在的文件夹,它包含在它创建编译的文件夹中。每个案例都有一个自述文件,详细说明了过程。

我尽量减少,我评论都是英文的。我删除了不需要的代码,但我添加了包含所有包含和使用的函数的文件。

这里是代码:

主.c

    key_t key, key_2;
int semid, semid_2;
union semun arg;
union semun arg_2;
struct sembuf sb_2 = {0, -1, 0};
char* nome_file;
nome_file = (char*) malloc(sizeof(char*));
int numero_clienti;

//semaphore for all the child
struct sembuf sb[numero_clienti];

int i_c;
for (i_c = 0; i_c < numero_clienti; i_c++) {
sb[i_c].sem_num = i_c;
sb[i_c].sem_op = -1;
sb[i_c].sem_flg = 0;

}
//cretion of first SEMAPHORE
{
//key creation
if ((key = ftok("cliente0.txt", 'J')) == -1)
{
perror("ftok");
exit(EXIT_FAILURE);
}
//creation of the semaphore
if ((semid = semget(key, numero_clienti, 0666 | IPC_CREAT | IPC_EXCL)) == -1)
{
perror("semget");
exit(EXIT_FAILURE);
}
//set value of all child semaphore
for (i_c = 0; i_c < numero_clienti; i_c++) {
arg.val = 0;
if (semctl(semid, i_c, SETVAL, arg) == -1)
{
perror("semctl");
exit(EXIT_FAILURE);
}
}

}
//cretion of second SEMAPHORE
{
//key creation
if ((key_2 = ftok("cliente1.txt", 'J')) == -1)
{
perror("ftok");
exit(EXIT_FAILURE);
}
//creation of the semaphore
if ((semid_2 = semget(key_2, 1, 0666 | IPC_CREAT | IPC_EXCL)) == -1)
{
perror("semget");
exit(EXIT_FAILURE);
}
//set value of parent semaphore
arg_2.val = 0;
if (semctl(semid_2, 0, SETVAL, arg_2) == -1)
{
perror("semctl");
exit(EXIT_FAILURE);
}
}

while(fd > 0 && pid > 0){


j++;

close(fd);
pid = fork();

if(pid != 0)
{
i++;
sprintf(nome_file, "./cliente%d.txt", i);
fd = open(nome_file, O_RDONLY);
}
switch(pid)
{
//error case
case -1:
{
perror("Error during fork.");
exit(EXIT_FAILURE);
break;
}
//child case
case 0:
{

puts("Child: I'm a child");
messaggio(numero_clienti, j);
puts("Child: I have to do something");

//Start parent
sb_2.sem_op = 1;
if (semop(semid_2, &sb_2, 1) == -1)
{
perror("semop");
exit(1);
}
//, stop itself
sb[j].sem_op = -1;
if (semop(semid, &sb[j], 1) == -1)
{
perror("semop");
exit(1);
}

printf("Child: I have to do something else %d\n", getpid());

_exit(EXIT_SUCCESS);
break;
}
//parent case
default:
{

puts("Parent: I'm a parent");

//Stop itself
sb_2.sem_op = -1;
if (semop(semid_2, &sb_2, 1) == -1)
{
perror("semop padre");
exit(1);
}

puts("Parent: now I can send the message, my child is blocked");

//restart child
sb[j].sem_op = 1;
if (semop(semid, &sb[j], 1) == -1)
{
perror("semop");
exit(1);
}
//stop itself
sb_2.sem_op = -1;
if (semop(semid_2, &sb_2, 1) == -1)
{
perror("semop");
exit(1);
}

puts("Parent: end of while");
break;
}
}
}
puts("Parent: I can restart all my child");

for (i_c = 0; i_c < numero_clienti; i_c++) {
sb[i_c].sem_op = 1;
if (semop(semid, &sb[i_c], 1) == -1)
{
perror("semop");
exit(1);
}
}

puts("I wait the end of my child...");
while (wait(NULL) != -1);

puts("All child end");

//remove semaphore I create
if (semctl(semid, 0, IPC_RMID, arg) == -1)
{
perror("semctl");
exit(1);
}

if (semctl(semid_2, 0, IPC_RMID, arg_2) == -1)
{
perror("semctl");
exit(1);
}

puts("FINE");
return 0;

}

客户端.c

#include "cliente.h"

/**
inside this function child do some thing.
1. at this point it give control to parent after it create a message
2. at this point it remove the message
*/
void messaggio(int numero_clienti, int num_j){
key_t key, key_2;
int semid, semid_2;
struct sembuf sb[numero_clienti];
int i_c;
for (i_c = 0; i_c < numero_clienti; i_c++) {
sb[i_c].sem_num = i_c;
sb[i_c].sem_op = -1;
sb[i_c].sem_flg = 0;

}
struct sembuf sb_2 = {0, -1, 0};

if ((key = ftok("cliente0.txt", 'J')) == -1) {
perror("ftok");
exit(1);
}

if ((semid = semget(key, 1, 0)) == -1) {
perror("semget");
exit(1);
}

if ((key_2 = ftok("cliente1.txt", 'J')) == -1) {
perror("ftok");
exit(1);
}

if ((semid_2 = semget(key_2, 1, 0)) == -1) {
perror("semget");
exit(1);
}
//creation of a message
//1. Restart parent
sb_2.sem_op = 1;
if (semop(semid_2, &sb_2, 1) == -1)
{
perror("semop");
exit(1);
}

puts("cambio sem");
//stop itself
sb[num_j].sem_op = -1;
if (semop(semid, &sb[num_j], 1) == -1)
{
perror("semop");
exit(1);
}
//here it can move again
puts("remove message");

puts("Figlio: sono tornato attivo, mio padre aspetta");

}

最佳答案

第一次做

nome_file = (char*) malloc(sizeof(char*));

分配 4 或 8 个字节(取决于您编译的平台:32 位或 64 位)。

然后你做

sprintf(nome_file, "./cliente%d.txt", i);

后者写入无效内存,如"./cliente%d.txt"是 14+1 个字符长加上来自 i 的潜在位数如果i>9或附加符号 i<0 .

要解决此问题,请分配所需内容:

nome_file = malloc(13 + 10 + 1 + 1); /* 13 for the filename, 
10 for the digits,
1 for a potential sign,
1 the C-"strings" 0-terminator. */

这是一个非常丑陋的错误,预计将成为您代码中的主要问题。


还有在函数read_line() 的源代码(您链接的)中你分配内存,你没有正确初始化,但后来取决于它的内容。

主.c:20

char* myb2 = (char*) malloc(sizeof(char*));

malloc()不初始化它分配的内存,所以要么:

char * myb2 = calloc(1, sizeof(char*));

添加和附加调用

memset(mb2, 0, sizeof(char*));

在调用 malloc() 之后.

这个错误也很讨厌。


另外^2 您应该使用 gcc 的选项 -std=c99 -D_XOPEN_SOURCE 进行构建.

那是因为:

  1. 您正在使用仅从 C99 开始可用的 C 结构。通常是 VLA,因此通过明确说明 -std=c99 告诉编译器将代码视为 C99 代码

  2. 收件人 #define _XOPEN_SOURCE由 gcc 发布,用于您在项目中包含的某些 header 。


还有 ^3 你似乎不一定计算正确的客户端(文件)数量,至少如果你的文件是按照你链接的存档分发的:

主.c:82

system("ls cliente* | wc -l");

将其更改为:

system("ls cliente*.txt | wc -l");

如果上述错误应该返回更多文件,那么实际上以下代码也会从 i 的某个值失败上:

主.c:176

fd = open(nome_file, O_RDONLY);

以上操作的结果测试。可能无效 fd被使用并且臭名昭着的未定义行为正在接管。一切皆有可能。


最后一点:它通常从不是我们使用的工具中的错误。

关于C Unix Xcode 再次出现错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27887612/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com