Меню сайта
ПОИСК ДЛЯ ПРОГРАММИСТОВ
Напоминаем, что если необходимый Вам файл был удален с сервера DepositFiles (за исключением просьбы автора), то Вы можете написать в комментарии о необходимости в данном файле. В ближайшее время он будет перезалит (при возможности на сервер сайта).
Главная » Файлы » Статьи
[ Добавить материал ]
Многопоточность в Си\С++
[
]
05.11.2008, 18:42
Кодирование файлов в несколько потоков
Code
#define _LARGEFILE64_SOURCE #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #include <sys/mman.h> #include <rpc/des_crypt.h> #include <pthread.h> #define SIZEOF_KEY (8) #define DECRYPT_NAME "decrypt" #define CHUNK_SIZE (128 * DES_MAXDATA) static int get_enc_mode (char * file_name) { return (strstr (file_name, DECRYPT_NAME) ? DES_DECRYPT : DES_ENCRYPT); } static int get_key (char * key, char * bin_key) { int i, j; memset (bin_key, 0, SIZEOF_KEY); j = 0; for (i = strlen (key) - 1; i >= 0; --i) { char nibble = 0; if (j >= SIZEOF_KEY * 2) return (EXIT_FAILURE); switch (key[i]) { case '0' ... '9': nibble = key[i] - '0'; break; case 'a' ... 'f': nibble = 0xa + key[i] - 'a'; break; case 'A' ... 'F': nibble = 0xA + key[i] - 'A'; break; default: return (EXIT_FAILURE); } if (j & 1) nibble <<= 4; bin_key[j >> 1] |= nibble; ++j; } return (EXIT_SUCCESS); } static int crypt_file (char * file_name, char * key, unsigned enc_mode) { int fd; int status = EXIT_SUCCESS; volatile off64_t offset = 0; pthread_mutex_t mutex; off64_t file_size; int n_cpus = 2 * (int) sysconf (_SC_NPROCESSORS_ONLN); pthread_t thr[n_cpus]; int i; int get_chunk (off64_t * offset_, int size) { pthread_mutex_lock (&mutex); *offset_ = offset; if (offset + size > file_size) size = file_size - offset; offset += size; pthread_mutex_unlock (&mutex); return (size); } int crypt_chunk (char * data, int size) { int chunk_offset = 0; while (chunk_offset < size) { int size_ = size - chunk_offset; if (size_ > DES_MAXDATA) size_ = DES_MAXDATA; int status = ecb_crypt (key, &data[chunk_offset], size_, enc_mode); chunk_offset += size_; if (DES_FAILED (status)) { fprintf (stderr, "Failed to crypt chunk. Error code is %d.\n", status); return (EXIT_FAILURE); } } return (EXIT_SUCCESS); } int handle_chunk (off64_t offset_, int size) { int status = EXIT_SUCCESS; char * data = mmap64 (NULL, size, PROT_WRITE, MAP_SHARED, fd, offset_); if ((char*)-1 == data) { fprintf (stderr, "Failed to map file into memory. Error code is %d.\n", errno); return (EXIT_FAILURE); } if (EXIT_SUCCESS != crypt_chunk (data, size)) status = EXIT_FAILURE; if (0 != msync (data, size, MS_SYNC)) { fprintf (stderr, "Failed to sync memory. Error code is %d.\n", errno); status = EXIT_FAILURE; } if (0 != munmap (data, size)) { fprintf (stderr, "Failed to unmap memory. Error code is %d.\n", status); status = EXIT_FAILURE; } return (status); } void * run_worker (void * arg) { off64_t offset_; int size; while ((size = get_chunk (&offset_, CHUNK_SIZE))) if (EXIT_SUCCESS != handle_chunk (offset_, size)) return ((void*)EXIT_FAILURE); return ((void*)EXIT_SUCCESS); } des_setparity (key); fd = open64 (file_name, O_RDWR); if (fd <= 0) { fprintf (stderr, "Failed to open the file `%s`. Return code is %d.\n", file_name, fd); return (EXIT_FAILURE); } file_size = lseek64 (fd, 0, SEEK_END); file_size &= ~((1 << SIZEOF_KEY) - 1); pthread_mutex_init (&mutex, NULL); for (i = 0; i < n_cpus; ++i) { if (pthread_create (&thr[i], NULL, run_worker, NULL)) return (EXIT_FAILURE); } for (i = 0; i < n_cpus; ++i) { int status_; pthread_join (thr[i], (void*)&status_); if (EXIT_SUCCESS != status_) status = EXIT_FAILURE; } fsync (fd); close (fd); fprintf (stderr, "%s %s. File '%s' %lld bytes.\n", (DES_ENCRYPT == enc_mode) ? "Encryption" : "Decryption", (EXIT_SUCCESS != status) ? "failed" : "successful", file_name, (long long int)file_size); return (status); } int main (int argc, char * argv[]) { int enc_mode = get_enc_mode (argv[0]); char key[SIZEOF_KEY]; if (3 != argc) { fprintf (stderr, "Wrong number of arguments %d.\n", argc); return (EXIT_FAILURE); } if (EXIT_SUCCESS != get_key (argv[2], key)) { fprintf (stderr, "Unexpected characters in a key '%s'.\n", argv[2]); return (EXIT_FAILURE); } return (crypt_file (argv[1], key, enc_mode)); }
Категория: Статьи |
Просмотров: 620 | Загрузок: 0
| Рейтинг: 0.0 /0 |
- Оценить -
Отлично
Хорошо
Неплохо
Плохо
Ужасно
Данный файл Вам очень помог? Вы можете отблагодарить автора!
Добавлять комментарии могут только зарегистрированные пользователи.
[
Регистрация |
Вход ]
Статистика
Онлайн всего: 1
Гостей: 1
Пользователей: 0