Среда, 25.06.2025, 04:10
СГУ.clan - в помощь студентам!
Главная | Регистрация |Вход Приветствую Вас Школьник | RSS
Меню сайта
ПОИСК ДЛЯ ПРОГРАММИСТОВ
 Google поиск для программистов
Категории каталога
Статьи [22]
Не СГУ [9]
Факультет КНиИТ [340]
Биологический факультет [16]
Географический факультет [31]
Геологический факультет [36]
Институт истории [67]
Механико-математический факультет [190]
Социологический факультет [68]
Фак-т нано и биомедицинских техн... [99]
Факультет нелинейных процессов [36]
Физический факультет [66]
Институт филологии и журналистики [29]
Химический факультет [70]
Экономический факультет [55]
Юридический факультет [31]
Наш опрос
Ваш курс?
Всего ответов: 387

Напоминаем, что если необходимый Вам файл был удален с сервера 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 |

Данный файл Вам очень помог? Вы можете отблагодарить автора!

Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Форма входа

Правильные покупки

Поиск
Друзья сайта


Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Copyright СГУ.clan © 2025