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

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

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 11.03.2011, 14:39   #1
добрый_фей
Пользователь
 
Регистрация: 01.11.2010
Сообщений: 17
Вопрос Синхронизация потоков

Доброго времени суток. Есть вопрос. Имеется следующий код: в главной функции создается поток F1, в котором имеется цикл до 4, при каждой итерации увеличивается число и присваевается следующему элементу массива. Потом все это дело должно распечататься в главной функции и продолжить выполнение потока и так безконца. Я реализовал это с помощью флага, но в таком случае в пустую тратятся ресурсы процессора, так как есть два цикла, которые выполнются пока состояние флага не изменится. Как это реализовать вместо флага, функциями из process.h если там таковые имеются, а если нет, то как это реализовать при помощи виндосовских функций.
П.С на мсдн смотрел, не разобоался, потому и спрашиваю.

Код:
#include<process.h>
#include<stdio.h>

int d[4];
int flag=1;

void F1(void *pParams)
{
	int i,num=0;
	while(1) 
		if(flag) {
			for(i=0;i<4;i++)
				*(d+i)=num++;
			flag=0;
		}
}

int main()
{
	_beginthread(F1,0,NULL);
	while(1)
		if(!flag) {
			printf("%d %d %d %d\n",*d,*(d+1),*(d+2),*(d+3));
			flag=1;
		}
	return 0;
}

Последний раз редактировалось AlDelta; 12.03.2011 в 01:23.
добрый_фей вне форума Ответить с цитированием
Старый 11.03.2011, 18:03   #2
eoln
Старожил
 
Аватар для eoln
 
Регистрация: 26.04.2008
Сообщений: 2,645
По умолчанию

Способы разные есть, самый короткий через WaitForSingleObject.
Код:
#include <stdio.h>
#include <pthread.h>
#include <process.h>

int d[4];

unsigned __stdcall F1(void *pParams)
{
	int i,num=0;
	for(i=0;i<4;i++)
	*(d+i)=num++;
	Sleep(2000);//так, для наглядности
	return 0;
}

int main()
{
	while(1)
	{
		HANDLE hThread_read=(HANDLE)_beginthreadex(NULL, 0, &F1, NULL, 0, NULL);//запускаем поток и запоминаем его хэндл
		printf("wait... ");
		WaitForSingleObject(hThread_read,INFINITE);//ждём заершения потока
		printf("ok\n");
		printf("%d %d %d %d\n",*d,*(d+1),*(d+2),*(d+3));
	}
	return 0;
}
eoln вне форума Ответить с цитированием
Старый 11.03.2011, 23:41   #3
добрый_фей
Пользователь
 
Регистрация: 01.11.2010
Сообщений: 17
По умолчанию

Тут получается, что процесс каждый раз завершается и вызывается заново, тоже самое, что вызывать функцию, а нужно, чтобы два процесса работали одновременно, просто синхронно, то есть, что бы в двух процессах был бесконечный цикл while(1), а где-то в циклах стояли бы функии- приостоновить процесс, пока другой не дойдет до такой же функции, которая скажет приостановить тот процесс, пока этот опять не дойдет до функции приостоновить этот процесс. Тоже самое, как с флагами, в моем варианте, только вместо флагов, функции, которые приостонавливали бы процесс, вместо того, что бы крутить цикл и просто не давать зайти в условие.
добрый_фей вне форума Ответить с цитированием
Старый 12.03.2011, 15:10   #4
eoln
Старожил
 
Аватар для eoln
 
Регистрация: 26.04.2008
Сообщений: 2,645
По умолчанию

Цитата:
Сообщение от добрый_фей Посмотреть сообщение
Тоже самое, как с флагами, в моем варианте, только вместо флагов, функции, которые приостонавливали бы процесс, вместо того, что бы крутить цикл и просто не давать зайти в условие.
Например, пусть потоки общаются через события. По сути это и есть флаги. Вместо условия IF будет ожидание WaitForSingleObject
Код:
#include <stdio.h>
#include <pthread.h>
#include <process.h>

int d[4];
HANDLE hEvent0=NULL, hEvent1=NULL;

unsigned __stdcall F1(void *pParams)
{
	while (1)
	{
		WaitForSingleObject(hEvent1, INFINITE);//ждать пока главный поток не создаст событие
		printf("thread work\n");
		int i,num=0;
		for(i=0;i<4;i++)
		*(d+i)=num++;
		ResetEvent(hEvent1);//сбросить событие для дочернего потока
		SetEvent(hEvent0);//создать событие для главного потока
	}
	return 0;
}

int main()
{
	hEvent0=CreateEvent( NULL,false, false, NULL);
	_beginthreadex(NULL, 0, &F1, NULL, 0, NULL);
	hEvent1=CreateEvent( NULL,false, true, NULL);
	while(1)
	{
		WaitForSingleObject(hEvent0, INFINITE);//ждать пока дочерний поток не создаст событие
		printf("programm work\n");
		printf("%d %d %d %d\n",*d,*(d+1),*(d+2),*(d+3));
		ResetEvent(hEvent0);//сбросить событие для главного потока
		SetEvent(hEvent1);//создать событие для дочернего потока
	}
	CloseHandle(hEvent0);
	CloseHandle(hEvent1);//удалять события не обязательно, т.к. работа бесконечная
	return 0;
}
eoln вне форума Ответить с цитированием
Старый 12.03.2011, 19:19   #5
добрый_фей
Пользователь
 
Регистрация: 01.11.2010
Сообщений: 17
По умолчанию

Спасибо! Именно это я и имел ввиду. Но немного подкорректировал, думаю эта тема полезна всем, кто незнаком с потоками или начинает их учить:

1. Не знаю, что такое pthread.h, у меня такого заголовочного файла нет, но с windows.h все прекрассно работает.
2. ResetEvent не нужно, так как функция CreateEvent во втором параметре определенна FALSE, то есть после выполнения функции WaitForSingleObject, событие автоматом сбрасывается.
3. Переменные должны определяться до цикла.

#include<stdio.h>
#include<windows.h>
#include<process.h>

int d[4];
HANDLE hEventMain=NULL,hEventF1=NULL;

unsigned __stdcall F1(void *pParams) {
int i,num=0;
while(1) {
WaitForSingleObject(hEventMain,INFI NITE);
for(i=0;i<4;i++)
*(d+i)=num++;
SetEvent(hEventF1);
}
return 0;
}

int main()
{
hEventMain=CreateEvent(NULL,FALSE,T RUE,NULL);
hEventF1=CreateEvent(NULL,FALSE,FAL SE,NULL);
_beginthreadex(NULL,0,&F1,NULL,0,NU LL);
while(1) {
WaitForSingleObject(hEventF1,INFINI TE);
printf("%d %d %d %d\n",*d,*(d+1),*(d+2),*(d+3));
getchar();
SetEvent(hEventMain);
}
CloseHandle(hEventF1);
CloseHandle(hEventMain);
return 0;
}
добрый_фей вне форума Ответить с цитированием
Старый 09.12.2011, 19:57   #6
chervet
Новичок
Джуниор
 
Регистрация: 09.12.2011
Сообщений: 1
По умолчанию

Доброго времени суток!
Хочу попросить помочь с решением, ибо в многопоточном программирование я профан, как впрочем и в программирование в целом.
Задача такова:

В парикмахерской расположено единственное кресло (разделяемый
ресурс), на котором спит парикмахер, и несколько стульев (разделяемые
ресурсы) для клиентов (потоки), которые делятся на два класса – обычные и «блатные». Сначала всегда обслуживаются «блатные» клиенты, и только после этого парикмахер может работать с обычными клиентами.
Когда клиент приходит в парикмахерскую, он будит парикмахера,
садится в кресло. Стрижка производится в течение заданного времени. Если же кресло занято другим клиентом, то вновь прибывший клиент занимает любой свободный стул и ожидает своей очереди. Далее клиенты обслуживаются в порядке приоритета и очередности (времени прибытия). Если все стулья заняты, то клиент поворачивается и уходит.
Когда обслужены все клиенты, парикмахер садится в кресло и снова
засыпает. Описанный процесс происходит бесконечно.
Воспользоваться объектами синхронизации типа «событие».

Мои попытки реализовать программу:

#include <windows.h>
#include <stdio.h>
#include <iostream>
using namespace std;
// глобальный описатель события со сбросом вручную (в занятом состоянии)
HANDLE g_hEvent;

int main()
{
// создаем объект "событие со сбросом вручную (в занятом состоянии)
HANDLE g_hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);

// порождаем 2 новых потока
HANDLE hThread[2];

DWORD dwThreadlD;

// Запускаем первый поток
hThread[0] = CreateEvent(NULL, 0, BLAT, NULL, 0, &dwThreadlD);
puts("Обслуживаются блатные клиенты");

// Запускаем первый поток
hThread[1] = CreateEvent(NULL, 0, NO_BLAT, NULL, 0, &dwThreadlD);
puts("Обслуживаются простые клиенты");
::SetEvent(g_hEvent);
}

DWORD WINAPI BLAT(PVOID pvParam)
{
// ждем,
WaitForSingleObject(g_hEvent, INFINITE);
// обращаемся к блоку памяти
Sleep(8000);
puts("Обслужаны блатные клиенты");
return(0);
}

DWORD WINAPI NO_BLAT(PVOID pvParam)
{
// ждем,
WaitForSingleObject(g_hEvent, INFINITE);
// обращаемся к блоку памят
Sleep(3000);
puts("Обслужаны простые клиенты");
return(0);
}

Компилятор всё время выводит ошибку по undeclared identifier.
chervet вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Синхронизация потоков kardinal94 Общие вопросы Delphi 5 29.11.2010 21:13
Синхронизация потоков alenka_ej Помощь студентам 0 03.06.2010 22:20
Синхронизация потоков в С++ erazer89 Помощь студентам 0 27.04.2010 20:14
синхронизация потоков m_kostik Win Api 0 26.03.2010 23:56