Debug Assertion Failed
06.04.2014, 19:37. Показов 415. Ответов 0
День добрый.
На С++ решаю задачу, схожую с "задачей производителя и потребителя". Вкратце: процесс Receiver запускает введенное пользователем количество процессов Sender, после чего начинает бесконечный цикл, в котором ждем команды: "прочесть", - прочесть запись из файла, "выход" - выход.
Процесс Receiver передает процессам Sender местоположение файла (общего для ресивера и всех сендеров) - контейнера сообщений.
Процессы Sender выполняют бесконечный цикл, в котором ждут команды: "писать" - записать запись в файл, "выход" - выход.
Проблема возникает тогда, когда после запуска процессом Receiver процессов Sender, в любом из последних при попытку открыть файл, выскакивает Debug Assertion Failed, скрин ниже.
код Receiver-а.
C++ | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
| #include <Windows.h>
#include <stdio.h>
#include <iostream>
using namespace std;
//структура записей в файл
struct record
{
bool free;
char name[20];
char message[30];
};
int main(int argc, char* argv[])
{
setlocale(0, "rus");
FILE* file;
HANDLE mutex;
//имя файла-контейнера
cout<<"Enter file-container name: ";
char file_name [25];
cin>>file_name;
char file_path[30];
sprintf(file_path, "%s%s", "D:\\", file_name);
//количество писателей
int writers_number = 0;
cout<<"Enter number of writers: ";
cin>>writers_number;
//количество записей
cout<<"Enter max number of records: ";
int records_number = 0;
cin>>records_number;
if(!(file=fopen(file_path, "wb")))
{
cout<<"Can't open file for read";
system("pause");
return 1;
}
//забиваем файл пустыми записями
record rec;
sprintf(rec.name, "%s", "");
sprintf(rec.message, "%s", "");
rec.free=true;
for (int i = 0; i < records_number; i++)
{
fwrite((void*)&rec, sizeof(record), 1, file);
}
fclose(file);
//мьютекс, будет регулировать доступ к файлу
mutex = CreateMutex(NULL, FALSE, "file_access");
//создаем процессы
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
char parametres [80];
sprintf(parametres, "%s%s", "Sender.exe ", file_path);
for (int i = 0; i < writers_number; i++)
{
if(!CreateProcess(NULL, parametres , NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi))
{
cout << "The mew process is not created." << endl
<< "Check a name of the process." << endl;
system("pause");
return 0;
}
}
char command[10];
while (true)
{
cout<<"Enter command: \"read\" to read or \"exit\" for exit: ";
cin>>command;
if(strcmp(command, "read")==0)
{
//захватываем мьютекс
WaitForSingleObject(mutex, INFINITE);
//открываем файл
if(!(file=fopen(file_path, "rb+")))
{
cout<<"Can't open file for read";
system("pause");
return 1;
}
//читаем запись
record rec;
rec.free=true;
while(!rec.free)
{
fread((void*)&rec, sizeof(record), 1, file);
}
//выводим прочитанное
cout<<"\t"<<rec.name<<"; "<<rec.message<<endl;
//двигаем назад, к началу того, где прочли
fseek(file, -(sizeof(record)), SEEK_CUR);
//записываем пустышку
rec.free = true;
sprintf(rec.name, "%s", "");
sprintf(rec.message, "%s", "");
fwrite((void*)&rec, sizeof(record), 1, file);
fclose(file);
//освобождаем файл
ReleaseMutex(mutex);
}
}
CloseHandle(pi.hThread);
CloseHandle(mutex);
system("pause");
return 0;
} |
|
код Sender-а
C++ | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
| #include <iostream>
#include <Windows.h>
struct record
{
bool free;
char name[20];
char message[30];
};
using namespace std;
int main (int argc, char *argv[])
{
setlocale(0, "rus");
char name[30];
cout<<"Enter name of the process: ";
cin.getline(name, 30);
FILE* file;
HANDLE mutex;
//открываем мьютекс
mutex = OpenMutex(SYNCHRONIZE, FALSE, (LPCWSTR)"file_access");
char command[10];
while (true)
{
cout<<"Enter command: \"write\" for write or \"exit\" for exit: ";
cin>>command;
if(strcmp(command, "write")==0)
{
[I]//открываем файл, тут и происходит ошибка
if(!(file=fopen(argv[2], "rb+")))[/I]
{
cout<<"Can't open file to write!";
cout<<endl;
system("pause");
return 1;
}
//читаем, пока не найдем свободную ячейку
record rec;
rec.free=false;
while(!rec.free)
{
fread((void*)&rec, sizeof(record), 1, file);
}
//двигаем назад к началу свободной
fseek(file, -sizeof(record), SEEK_CUR);
char message[20];
cout<<"Enter message: ";
cin.ignore();
cin.getline(message, 20);
//записываем новую запись
rec.free=false;
sprintf(rec.name, "%s", name);
sprintf(rec.message, "%s", message);
fwrite((void*)&rec, sizeof(record), 1, file);
fclose(file);
ReleaseMutex(mutex);
}
else if(strcmp(command, "exit")==0) return 0;
}
} |
|
Знаю, что для полной реализации еще надо дозапилить семафоры, но пока споткнулся на разграничении доступа к чтению-записи
Добавлено через 57 минут
upd: забыл добавить: если отлаживать просто процесс Sender, все в порядке, ошибки нет. Возникает она в случае, если сендер вызван Ресивером.
0
|