Напишите программу на языке C/C++, в которой:
1) Запускается четное количество потоков параллельно.
2) Каждый нечетный поток (например, первый) создает файл с именем из
своего PID, записывает в него произвольное число символов (от не-
скольких символов до сотен миллионов символов) и закрывает этот
файл.
3) Каждый четный поток (например, второй) открывает файл, созданный
предыдущим потоком с нечетным номером (в нашем случае первым),
читает его, считает количество символов в файле и закрывает его; при
этом четный поток не должен иметь никакой информации о количест-
ве записываемых в файл символов и о том, закончена ли запись в файл
нечетным потоком.
4) Каждый из потоков выводит следующую информацию: ThreadID, PID,
PPID, время, имя файла, количество записанных или считанных сим-
волов.
5) Количество пар создаваемых потоков передается аргументом в про-
грамму с командной строки. Программа должна ждать завершения
работы всех потоков, анализировать и сообщать о причинах заверше-
ния потоков. Для передачи имен файлом между потоками можно ис-
пользовать символьный массив в основной программе.
// ОС: Ubuntu 12.04
// Среда разработки: Eclipse Platform Version: 3.7.2
// C++
#include
#include
#include
#include
#include
#include
char** files; // массив с именами файлов
void* create_file(void *arg) // поток создания файла
{
int ind = (int) arg; // индекс указывающий на имя файла
FILE* fl;
long unsigned int PID;
int pid, ppid, num;
long unsigned int len, i = 0;
char buf, t[32];
time_t seconds;
tm* timeinfo;
num = ind*2 + 1; // номер потока
len = random(); // количество символов в файле
PID = pthread_self(); // ThreadID
pid = getpid(); // PID
ppid = getppid(); // PPID
sprintf(files[ind], "%s/%lu%s", getenv("HOME"), PID, ".txt"); // имя файла
seconds = time(NULL);
timeinfo = localtime(&seconds);
strcpy(t,asctime(timeinfo));// время
fl = fopen(files[ind], "w");// создаем файл
if( fl ) // если файл создан
{
while( i!=len) // пока не запишем все символы
{
if( i % 2 ) buf = '0';
else buf = '1';
fputc(buf, fl); // записываем символ в файл
i++;
}
fclose(fl); // закрываем файл
}
// выводим на экран информацию о потоке и файле
printf("\nThread #%i\n\tThreadID: %lu\n\tPID: %i\n\tPPID: %i\n\tTimeDate: %s\tFileName: %s\n\tLength: %lu\n", num, PID, pid, ppid, t, files[ind], len);
pthread_exit(NULL);
}
void* read_file(void *arg) // поток читающий файл
{
int ind = (int) arg; // индекс указывающий на имя файла
FILE* fl;
long unsigned int PID;
int i = 0, pid, ppid, num;
long int len = 0;
char t[32];
char buf[256];
time_t seconds;
tm* timeinfo;
num = ind*2 + 2;
PID = pthread_self(); // ThreadID
pid = getpid(); // PID
ppid = getppid(); // PPID
seconds = time(NULL);
timeinfo = localtime(&seconds);
strcpy(t,asctime(timeinfo)); // время
fl = fopen(files[ind], "r"); // открываем файл для чтения
if( fl ) // если файл открылся
{
strcpy(buf, files[ind]); // считываем название файла
while( i!=EOF ) // пока не достигнем конца файла
{
i = fgetc(fl); // считываем по-символьно
if( i!=EOF ) len++; // счетчик символов
}
fclose(fl); // закрываем файл
}
else // если файла нет
{
strcpy(buf, "file not found");
}
// выводим результаты работы
printf("\nThread #%i\n\tThreadID: %lu\n\tPID: %i\n\tPPID: %i\n\tTimeDate: %s\tFileName: %s\n\tLength: %lu\n", num, PID, pid, ppid, t, buf, len);
pthread_exit(NULL);
}
// запускаем приложение
int main(int argc, char* argv[])
{
int i, qnt, res, tmp;
FILE* fl;
pthread_t* ws;
pthread_t* rs;
srandom(time(NULL));
if( argc == 2 ) qnt = atoi(argv[argc-1]); // выбираем количество пар потоков из командной строки
else qnt = 0;
if( qnt ) // если в командной строке прописано количество пар потоков
{
ws = new pthread_t[qnt]; // создаем указатели на потоки записи
rs = new pthread_t[qnt]; // создаем указатели на потоки чтения
files = new char*[qnt]; // создаем массив имен файлов
for(i=0; i
{
files[i] = new char[256]; // инициализируем строку имени файла
res = pthread_create(&ws[i], NULL, create_file, (void*)i); // запускаем нечетный поток
if (res != 0) // проверка на успех
{
perror("creation failed");
exit(EXIT_FAILURE);
}
res = pthread_create(&rs[i], NULL, read_file, (void*)i); // запускаем четный поток
if (res != 0) // проверяем
{
perror("Thread creation failed");
exit(EXIT_FAILURE);
}
}
// проверяем завершение потоков, а так же удаляем файлы и очищаем память
for(i=qnt-1; i>=0; i--)
{
tmp = i*2+1;
res = pthread_join(ws[i], NULL);
if (res == 0) printf("Picked up a thread #%i\n", tmp);
else perror("pthread_join failed");
tmp = i*2+2;
res = pthread_join(rs[i], NULL);
if (res == 0) printf("Picked up a thread #%i\n", tmp);
else perror("pthread_join failed");
fl = fopen(files[i], "r");
if( fl )
{
fclose(fl);
remove(files[i]);
}
delete [] files[i];
}
// очищаем память
delete [] files;
delete [] ws;
delete [] rs;
}
// завершение работы
printf("All done\n");
exit(EXIT_SUCCESS);
}
|