Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.09.2011, 23:04   #1
Farrel
Форумчанин
 
Аватар для Farrel
 
Регистрация: 21.04.2010
Сообщений: 144
По умолчанию возникла необходимость создать несколько потоков

Походу вопрос в эту ветку.
В общем возникла необходимость создать несколько потокв приблизительно таким образом:
Код:
for(i=0;i<20;i++)
  {
    f[0]=fopen(files[i],"r");	//open sourse
    i++;
    f[1]=fopen(files[i],"w+");	//open distanation file
	h[(i-1)/2]=CreateThread(0, 0,(LPTHREAD_START_ROUTINE) moveth, f, 0, 0);
	//moveth((LPVOID*)f);
  }
  WaitForMultipleObjects(10,h,true,INFINITE);
Весь код приводить в принципе бесмыссленно. В вышеописанном кусочке пытаюсь запустить 10 потоков, которые будут выпролнять функцию moveth (она занимается копированием файлов). Собственно вопрос в следующем: если при создании потоков использовать одну и ту же функцию, то будут ли потоки независимы? или же они могут помешать выполниться друг другу?(то что я видел при дебаге доказывало последнее). И если это так, то каким образом можно реализовать выполнение нескольких потоков созданных с исполльзованием одной и той же функции.
Farrel вне форума Ответить с цитированием
Старый 19.09.2011, 12:33   #2
rpy3uH
добрый няша
Старожил
 
Аватар для rpy3uH
 
Регистрация: 29.10.2006
Сообщений: 4,804
По умолчанию

если код в поточных функциях написал правильно, то всё будет хорошо, запускай хоть 100 копий. основная проблема, это синхронизация доступа к общим переменным. Использование любой глобальной переменной должно быть синхронизировано.

код функции moveth в студию!
rpy3uH вне форума Ответить с цитированием
Старый 19.09.2011, 21:49   #3
Farrel
Форумчанин
 
Аватар для Farrel
 
Регистрация: 21.04.2010
Сообщений: 144
По умолчанию

Код:
DWORD moveth(LPVOID files)		//moving file function
{
  FILE** f=(FILE**)files;
  int filelen;
  int i;
  char c;
  
  fseek(f[0], 0, SEEK_END);		//fet file size
  filelen=ftell(f[0]);
  fseek(f[0], 0, SEEK_SET);
  for(i=0;i<filelen;i++)		//copy
  {
    fread(&c, 1, 1, f[0]);
    fwrite(&c, 1, 1, f[1]);
  }
  fclose(f[1]);
  fclose(f[0]);
	return NULL;
}
Будучи запущеной в цикле работает 100%, а вот при использовании потоков трабл.
Farrel вне форума Ответить с цитированием
Старый 19.09.2011, 22:27   #4
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

Цитата:
Сообщение от Farrel Посмотреть сообщение
Код:
DWORD moveth(LPVOID files)		//moving file function
{
  FILE** f=(FILE**)files;
  int filelen;
  int i;
  char c;
  
  fseek(f[0], 0, SEEK_END);		//fet file size
  filelen=ftell(f[0]);
  fseek(f[0], 0, SEEK_SET);
  for(i=0;i<filelen;i++)		//copy
  {
    fread(&c, 1, 1, f[0]);
    fwrite(&c, 1, 1, f[1]);
  }
  fclose(f[1]);
  fclose(f[0]);
	return NULL;
}
Будучи запущеной в цикле работает 100%, а вот при использовании потоков трабл.
Что, в общем-то, не странно, так как налицо несколько ошибок. Во-первых, необходимость принудительного преобразования к LPTHREAD_START_ROUTINE должна была насторожить вас и намекнуть, что moveth определена неправильно. Необходимо указать, что moveth должна использовать соглашение по вызову stdcall, а не ccall, это можно сделать директивой __stdcall или макросом WINAPI
Код:
DWORD WINAPI moveth(LPVOID files)
Во-вторых, Вы используете разделяемую переменную f, которая используется всеми созданными потоками, что не есть хорошо, так как новосозданный поток может не успеть прочесть имя файла до того, как оно будет затёрто на очередной итерации цикла основного потока.
Итак, чтобы избавиться от ошибок, необходимо:
1. Исправить определение функции moveth
2. Избежать использования разделяемой переменной f (сие сделать можно несколькими путями, один из них: на каждой итерации цикла выделять память для f в куче и передавать указатель на неё в moveth, а после открытия файлов, не забыть освободить память, уже внутри moveth)
netrino вне форума Ответить с цитированием
Старый 19.09.2011, 23:04   #5
Farrel
Форумчанин
 
Аватар для Farrel
 
Регистрация: 21.04.2010
Сообщений: 144
По умолчанию

О, сеньк народ! Действительно с stdcall прокололся. Да и испоьзование разделяемой переменной тоже просмотрел. Во 2-й ошибке суда по всему и заключается проблема процентов на 90. Покопаюсь как раз в способах синхронизации.
Farrel вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Логгирование, несколько потоков pa6kevi4 Общие вопросы .NET 3 12.06.2010 22:32
[Вопрос] IdHttp в несколько потоков TilerDerton Работа с сетью в Delphi 3 22.09.2009 22:14
Загрузка файла в несколько потоков Joe_Tribbiani Работа с сетью в Delphi 12 11.04.2009 12:06
Несколько потоков Adm Общие вопросы Delphi 13 18.01.2008 20:04