ПРИМЕР: создание потока (нити) winapi си (пример win api) для windows

Начиная эту заметку я , присоединяясь к мыслям высказывания, процитирую =

This article is meant for beginners who want to take initial lessons in creating threads. This article explains how to create threads using the CreateThread() function. When I started to learn multithreaded programming, I had a very hard time finding simple and descriptive programs and articles that would demonstrate and explain concepts related to multithreading in simple plain English. And this is what motivated me to write my first article on multithreading, for CodeProject.

Итак , рассмотрим пример создание нового потока на си в windows , прототип функции CreateThread() ,которая как раз и запускает исполняемый код в виде отдельного потока вы можете увидеть здесь

В данной же теме мы займёмся рассмотрим конкретный пример, связанный с задачей создания нового потока (нити).

Рассмотрим пример. Пусть у нас есть код типа (две функции - вторая вызывает первую) =

/*операции этой функции по сравнению двух текстовых файлов
построчно -  будут запущены в виде отдельного процесса*/
int task1comp(FILE* fp,FILE* fp2,FILE* rfp) // это функция просто
{
     char **arr1,**arr2;
	 
	 arr1 = tfile_to_tdarr(fp); // считываем строки из первого текстового файла и размещаем их массиве
	 arr2 = tfile_to_tdarr(fp2);// считываем строки из второго текстового файла и размещаем их массиве
	 
	 /*выведем содержимое текстовых фалов на экран*/ 
	 tdarr_show(arr1); // выводим на экран массив , полученный из строк 1-ого из сравниваемых построчно текстовых файлов
	 tdarr_show(arr2); // выводим на экран массив , полученный из строк 2-ого из сравниваемых построчно текстовых файлов
	 
	 
	 /*сравниваем массивы строк*/
	 tdarrs_cmp(arr1,arr2,rfp); // передаём два массива и указатель на файл в который запишем результат сравнения двумерных массивов, полученных из двух текстовых файлов.
	 
	 /*заврываем открытые файлы*/
	 fclose(fp); // закрываем первый , из двух файлов, которые мы сравнивали между собой
	 fclose(fp2); // закрываем второй , из двух файлов, которые мы сравнивали между собой
	 fclose(rfp); // закрываем файл, в который мы записывали результат
	 
	 return 0;
 } 

int task1standard(void) // это функция просто 
{
    FILE *fp,*fp2,*rfp;
	
    fp = openfileforme("123.txt","r");
	fp2 =openfileforme("321.txt","r");
	rfp =openfileforme("111.txt","w");
	
	/*вызовем функцию сравнения в виде отдельной нити*/
	 task1comp(fp,fp2,rfp); // вызываем функцию сравнения 
	 
	 return 0;

	
}

в данном случае я попытаюсь создать новый поток в рамках функции task1standard(void) - вместо вызова функции =

	 task1comp(fp,fp2,rfp); // вызываем функцию сравнения 

я попробую создать уже отдельный поток, который будет выполнять эту функцию в windows.

О том как передать несколько параметров потоку (нити) в windows = читайте здесь
итак, попробуем.

Дело в том, что функция создания потока , в качестве одного из своих параметров требует указателя на функцию , код которой будет исполняться в контексте потока.

Новый поток(нить) в windows с помощью языка си можно создать использую функцию CreateThread() о её параметрах на русском можете прочитать здесь.

Но функция, код которой будет исполняться в теле (контексте) процесса должна в виндоус обладать особым возвращаемым значением (типом возвращаемого значения) и соответствовать следующему объявлению (по типу и количеству принимаемых значений) =

DWORD WINAPI ThreadFunction(LPVOID lpParameter);

В связи с этим, нам будет удобнее создать функцию обёртку для нашей "рабочей" функции task1comp() , в результате мы получаем следующий код =

int task1comp(FILE* fp,FILE* fp2,FILE* rfp) // это функция просто
{
     char **arr1,**arr2;
	 
	 arr1 = tfile_to_tdarr(fp); // считываем строки из первого текстового файла и размещаем их массиве
	 arr2 = tfile_to_tdarr(fp2);// считываем строки из второго текстового файла и размещаем их массиве
	 
	 /*выведем содержимое текстовых фалов на экран*/ 
	 tdarr_show(arr1); // выводим на экран массив , полученный из строк 1-ого из сравниваемых построчно текстовых файлов
	 tdarr_show(arr2); // выводим на экран массив , полученный из строк 2-ого из сравниваемых построчно текстовых файлов
	 
	 
	 /*сравниваем массивы строк*/
	 tdarrs_cmp(arr1,arr2,rfp); // передаём два массива и указатель на файл в который запишем результат сравнения двумерных массивов, полученных из двух текстовых файлов.
	 
	 /*заврываем открытые файлы*/
	 fclose(fp); // закрываем первый , из двух файлов, которые мы сравнивали между собой
	 fclose(fp2); // закрываем второй , из двух файлов, которые мы сравнивали между собой
	 fclose(rfp); // закрываем файл, в который мы записывали результат
	 
	 return 0;
 } 


int task1standard(void) // это функция просто 
{
    FILE *fp,*fp2,*rfp;
	
    fp = openfileforme("123.txt","r");
	fp2 =openfileforme("321.txt","r");
	rfp =openfileforme("111.txt","w");
	
	
/*----------часть использующая типы и правила винды-------*/
	HANDLE handle_of_comp; // идентификатор процесса сравнени
	
	/*вызовем функцию сравнения в виде отдельной нити*/

    /*определение структуры использованной в следующей	строчке находится в загловочном файле winfunc.h*/
	  struct winparams t1winp ; // эта переменная будет хранить несколько  - три параметра, передаваемые в новый поток windows  - "набиваем" её полученными выше значениями в трёх строчках ниже =
	t1winp.fp = fp; 
	t1winp.fp2 =fp2;
	t1winp.rfp = rfp;
	
	handle_of_comp = CreateThread( // СОЗДАЁМ ПОТОК (НИТЬ)
	                                NULL, // вместо дескриптора защиты
	                                0, // вместо начального дискриптора стека
									t1_win_comp, // имя нашей функции - которую мы запустим в новом потоке  - файл с её описание должен быть опключён
									&t1winp, // указатель на пареметр передаваемый функции  - т.е. на нашу структуру
									0, // вместо опций создания
									NULL); // вместо идентифйикатора потока
								
	 
	 
	 WaitForSingleObject(handle_of_comp ,1000); // ждём статуса завершения потока
	 return 0;

	
}

DWORD WINAPI t1_win_comp( LPVOID lpParam ) // функция-обёртка для task1comp()
{
   
    struct winparams strct= *((struct winparams*)lpParam); // приводим к типу нашей структуры , данные расположенные по адресу указателя 
	//printf("{{{test-test-test}}}\n"); // это отладочнвя строка
   task1comp(strct.fp,strct.fp2,strct.rfp); // вызываем ключевыую функцию сравнения.
   return 0;
}

кстати структура типа struct winparams в моём случае имела вид (я объявлял её в отдельном заголовочном включаемом файле)=

 struct winparams { // структура для передачи параметров в объединённом виде для потока в windows
		 FILE *fp; // указатель на первый файл
		 FILE *fp2; // указатель на втоорй файл
		 FILE *rfp; // указатель на файл, для записи результата
	 } ; 
	 

Заметьте , что нам приходится исопльзвать структуру, так как в функцию-обёртку в соответствии с правилами Билли и его разработчиков можно передать только один параметр - а точнее указатель только на единственную единую =)) область памяти.
Подробнее о передаче параметров в поток читайте здесь.

Если не использовать синхронизацию, то вы можете получить ошибку времени выполнения - подробнее о том как подождать завершения дочернего потока читайте здесь

_____________________________________________
Источники(читать подробнее)=
http://stackoverflow.com/questions/14564...
http://stackoverflow.com/questions/33153...
http://msdn.microsoft.com/en-us/library/...
http://stackoverflow.com/questions/51744...
Ключевые слова и фразы(для поиска)=
создание потока windows си
Creating a new thread (C, Windows)
create thread c example windows
pass several parameters to tread c windows
передать несколько параметров в поток нить си
создание потока си