Подсчет контрольной суммы файла
Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain
Общие требования
Любые данные в памяти, а также другие ресурсы (экран, файлы), которые могут использованы более одной нитью, и в которые хотя бы одна нить может производить запись, должны быть защищены мьютексом (или семафором). Защита означает, что перед доступом к данным или ресурсу нужно вызвать функцию pthread_mutex_lock (или sem_wait), а после доступа - функцию pthread_mutex_unlock (или sem_post). При этом для каждого ресурса и для каждого логически связанного блока данных нужно использовать свой мьютекс (семафор).
Если явно не cказано, то предполагается, что число нитей в программе равно k, при этом параметр k и другие параметры нужно передавать программе в командной строке, или вводить с клавиатуры (если их немного) или из файла.
Любые данные в памяти, а также другие ресурсы (экран, файлы), которые могут использованы более одной нитью, и в которые хотя бы одна нить может производить запись, должны быть защищены мьютексом (или семафором). Защита означает, что перед доступом к данным или ресурсу нужно вызвать функцию pthread_mutex_lock (или sem_wait), а после доступа - функцию pthread_mutex_unlock (или sem_post). При этом для каждого ресурса и для каждого логически связанного блока данных нужно использовать свой мьютекс (семафор).
Если явно не cказано, то предполагается, что число нитей в программе равно k, при этом параметр k и другие параметры нужно передавать программе в командной строке, или вводить с клавиатуры (если их немного) или из файла.
этого достаточно? могу еще узнать
ну вы где? мне до 5 числа надо ее решить. алгоритм хоть скажите
чето я не понимаю твою задачу.
Поидее от тебя ждут, что твой процесс создаст N потоков, опделит размер файла (Size)
каждый поток будет считать контрольную сумму своего участка (участок вычислить легко: i * Size/N, где i - порядковый номер потока.
затем какойто один поток объеденит контрольные суммы.
И это хорошо, но мне чето непонятно зачем тут семафоры и прочие штуки. Ты же с файла будешь читать, разве несколько потоков не могут делать это параллельно? - я думаю что мутексы нужны если потоки могли бы параллельно писать в файл. Зачем тебе тутблокировки я не пойму короче.
Поидее от тебя ждут, что твой процесс создаст N потоков, опделит размер файла (Size)
каждый поток будет считать контрольную сумму своего участка (участок вычислить легко: i * Size/N, где i - порядковый номер потока.
затем какойто один поток объеденит контрольные суммы.
И это хорошо, но мне чето непонятно зачем тут семафоры и прочие штуки. Ты же с файла будешь читать, разве несколько потоков не могут делать это параллельно? - я думаю что мутексы нужны если потоки могли бы параллельно писать в файл. Зачем тебе тутблокировки я не пойму короче.
Приглашаю на свой блог о программировании: pro-prof.com
Код: Выделить всё
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <pthread.h>
/*
Ïîäñ÷žò êîíòðîëüíîé ñóììû ôàéëà (ñóììû áàéò ïî ìîäóëþ 256).
Íèòü ñ÷èòûâàåò ó÷àñòîê ôàéëà è ñ÷èòàåò åãî ñóììó.
Ðåçóëüòàòû ñêëàäûâàþòñÿ.
*/
char* filename;
FILE* f;
int* ans;
int filesize, numblocks, blocksize;
pthread_t *tblock;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int CalculateBlockSize(int size, int numblocks)
{
return size/numblocks+1;
}
void* run (void* arg)
{
int thread_idx;
int * thread_ptr;
thread_ptr=(int *)arg;
thread_idx=*thread_ptr;
pthread_mutex_lock(&mutex);
printf("\nStart thread %d\n",thread_idx);
pthread_mutex_unlock(&mutex);
pthread_mutex_lock(&mutex);
char* buffer = new char[blocksize];
fseek(f, blocksize*thread_idx, SEEK_SET);
printf("Thread %d position in file %d\n", thread_idx, ftell(f));
int csize=fread(buffer,1,blocksize,f);
rewind(f);
pthread_mutex_unlock(&mutex);
int mem=0;
for (int i=0; i<csize; i++)
{
mem+=buffer[i];
mem%=256;
}
pthread_mutex_lock(&mutex);
ans[thread_idx]=mem;
pthread_mutex_unlock(&mutex);
free(buffer);
pthread_exit(0);
}
int main(int argc, char* argv[])
{
if (argc<2) {printf("Need more arguments!\n"); exit(-2);}
int s;
filename=argv[1];
f=fopen(filename, "rb");
fseek (f, 0, SEEK_END);
filesize=ftell(f);//òóò ìû íàøëè ðàçìåð ôàéëà
numblocks=atoi(argv[2]);//òåïåðü íàäî êàê-òî îêðóãëèòü äî êðàòíîãî ñòåïåíè äâîéêè. â èäåàëå ýòî áóäåò äåëàòü CalculateBlockSize
ans = new int[numblocks];
tblock = new pthread_t[numblocks];
int* numbers=new int[numblocks];
for (int k=0;k<numblocks;k++)
{
numbers[k]=k;
}
blocksize=CalculateBlockSize(filesize, numblocks);
printf("%d %d %d\n", filesize, numblocks, blocksize);
rewind(f);
int i=0;
while (i<numblocks)
{
s=pthread_create(
&tblock[i],
NULL,
&run,
&numbers[i]
);
i++;
if (s!=0)
{
printf("error creating thread number %d\n",i);
exit(-1);
}
}
for (int j=0; j<i; j++) {
s=pthread_join(tblock[j],NULL);
if (s!=0)
{
printf("error finishing thread %d\n",j);
}
printf("\nFinished thread %d\n",j);
}
int mem1=0;
for(i=0;i<numblocks;i++)
{
mem1+=ans[i];
mem1%=256;
}
pthread_mutex_destroy(&mutex);
printf("\nResult=%d\n", mem1);
free(ans);
free(tblock);
free(numbers);
return 0;
}
вот это код программы
при компидяции выводит следующее:
sony@ubuntu:~$ g++ 1.4.cpp -o 1.4
1.4.cpp: В функции «void* run(void*)»:
1.4.cpp:39:67: предупреждение: format «%d» expects argument of type «int», but argument 3 has type «long int» [-Wformat]
/tmp/ccQ2rHC6.o: In function `main':
1.4.cpp
.text+0x32e): undefined reference to `pthread_create'
1.4.cpp
.text+0x396): undefined reference to `pthread_join'
collect2: выполнение ld завершилось с кодом возврата 1
sony@ubuntu:~$
что не так?
при компидяции выводит следующее:
sony@ubuntu:~$ g++ 1.4.cpp -o 1.4
1.4.cpp: В функции «void* run(void*)»:
1.4.cpp:39:67: предупреждение: format «%d» expects argument of type «int», but argument 3 has type «long int» [-Wformat]
/tmp/ccQ2rHC6.o: In function `main':
1.4.cpp

1.4.cpp

collect2: выполнение ld завершилось с кодом возврата 1
sony@ubuntu:~$
что не так?
это код программы
при компиляции выдает следующее:
sony@ubuntu:~$ g++ 1.4.cpp -o 1.4
1.4.cpp: В функции «void* run(void*)»:
1.4.cpp:39:67: предупреждение: format «%d» expects argument of type «int», but argument 3 has type «long int» [-Wformat]
/tmp/ccQ2rHC6.o: In function `main':
1.4.cpp
.text+0x32e): undefined reference to `pthread_create'
1.4.cpp
.text+0x396): undefined reference to `pthread_join'
collect2: выполнение ld завершилось с кодом возврата 1
sony@ubuntu:~$
что не так?
при компиляции выдает следующее:
sony@ubuntu:~$ g++ 1.4.cpp -o 1.4
1.4.cpp: В функции «void* run(void*)»:
1.4.cpp:39:67: предупреждение: format «%d» expects argument of type «int», but argument 3 has type «long int» [-Wformat]
/tmp/ccQ2rHC6.o: In function `main':
1.4.cpp

1.4.cpp

collect2: выполнение ld завершилось с кодом возврата 1
sony@ubuntu:~$
что не так?
- Romeo
- Сообщения: 3126
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
Ubuntu под рукой нету, так что я собрал и запустил твою программу на AIX 6.1. Компилируется и даже работает. Я создал тектовый файл и скормил ему. Вот вывод:
Либо компилятор на Ubuntu ни разу не POSIX, либо прототипы функций для работы с тредами лежат у него не в стандартом инклюд-файле pthread.h. Открой этот инклюд-файл и поищи есть ли они там.$ test.exe file.in
1148 0 1
Result=0
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
- Romeo
- Сообщения: 3126
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
Это относительно того компилируется или не компилируется. Если же почитать сам код программы, то у меня возникает такой же вопрос, как и у rrrFer. Зачем тут мьютекс и блокировки, если треды не пишут в файл? Просто для того, чтобы потренироваться?
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
g++ 1_4.cpp -o 1_4 -lpthread
компилируем так , все нормально.
потом ввожу
./1_4
и в ответ
need more argument!
что надо делать?
компилируем так , все нормально.
потом ввожу
./1_4
и в ответ
need more argument!
что надо делать?