LINUX.ORG.RU

Producer <-> Consumer


0

0

Я не очень силен в много-поточном программировании , поэтому предлагаю
вам посмотреть на этот код и подсказать , где могут быть подводные камни 
У меня все работает , но как-то все подозрительно гладко   
Имеется общий ресурс - очередь
Имеются 2 группы по пять потоков  
Обе группы начинают коллективно насиловать эту очередь
Первая группа добавляет в очередь , вторая - забирает
Все написано в лучших традициях ричарда незабвенного нашего стивенса 

#define	MAXNITEMS 		1000000
#define	MAXNTHREADS			100

int		nitems;			

struct node* List ;

struct {
  pthread_mutex_t	mutex;
  pthread_cond_t	cond;
  int				nready;	
  int	count;
  long producer_sum  ;
  struct node* List ;
} put = { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER };

struct {
  pthread_mutex_t	mutex;
  pthread_cond_t	cond;
  int				nready;	
  int	count;
  long consumer_sum  ;
  struct node* List ;
} get = { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER };

void	*produce(void *), *consume(void *);
int  Length(char * name , struct node* head);
int  Pop(struct node** headRef);
void Add(struct node** headRef, int num) ;
 
int main(int argc, char **argv)
{
	int			i, nthreads, count[MAXNTHREADS] , count2[MAXNTHREADS];
	pthread_t	tid_produce[MAXNTHREADS], tid_consume[MAXNTHREADS];

	List = NULL ;

	if (argc != 3)
	{
		printf("usage: prodcons2 <#items> <#threads>\n");
		exit(0);
	}
	nitems = atoi(argv[1]);
	nthreads = atoi(argv[2]);

	for (i = 0; i < nthreads; i++) 
	{
		count[i] = 0;
		pthread_create(&tid_produce[i], NULL, produce, &count[i]);
		count2[i] = 0;
		pthread_create(&tid_consume[i], NULL, consume, &count2[i]);
	}

	for (i = 0; i < nthreads; i++) 
	{
		pthread_join(tid_produce[i], NULL);
		pthread_join(tid_consume[i], NULL);
		printf("count[%d] = %d  count2[%d] = %d\n", i, count[i], i, count2[i]);	
	}

	printf("producer_sum =%d  consumer_sum =%d\n" , put.producer_sum , get.consumer_sum);  // results in len == 3
	printf("producer counter =%d  consumer counter =%d\n" , put.count , get.count);  // results in len == 3
    printf("queue length =%d\n",Length("List",List));  // results in len == 3

	exit(0);
}

void * produce(void *arg)
{
	for ( ; ; ) {
		pthread_mutex_lock(&put.mutex);
		if (put.count >= nitems) {
			pthread_mutex_unlock(&put.mutex);
			return(NULL);		/* array is full, we're done */
		}
		Add(&List, put.count ); 
		put.producer_sum +=put.count;
		put.count++;
//		printf("producer =%d  consumer =%d\n" , put.count , get.count);  // results in len == 3
		pthread_mutex_unlock(&put.mutex);

		pthread_mutex_lock(&get.mutex);
		if (get.nready == 0)
			pthread_cond_signal(&get.cond);
		get.nready++;
		pthread_mutex_unlock(&get.mutex);

		*((int *) arg) += 1;
	}
	return(NULL);		/* array is full, we're done */
}

void * consume(void *arg)
{
	for ( ; ; ) {
			pthread_mutex_lock(&get.mutex);
			if (get.count >= nitems ) 
			{
				pthread_mutex_unlock(&get.mutex);
				return(NULL);		/* array is full, we're done */
			}
			if(get.count < put.count)
			{
				int queue = Pop(&List ); 
				get.consumer_sum += queue;
				get.count ++;
//				printf("producer =%d  consumer =%d\n" , put.count , get.count);  // results in len == 3
				*((int *) arg) += 1;
			}
			pthread_mutex_unlock(&get.mutex);
	
			pthread_mutex_lock(&put.mutex);
			if (put.nready == 0)
				pthread_cond_signal(&put.cond);
			put.nready++;
			pthread_mutex_unlock(&put.mutex);
	}
	return(NULL);
}
★★★★★

Re: Producer <-> Consumer

за вшивание конфига в код...

#define	MAXNITEMS 		1000000
#define	MAXNTHREADS			100

казнить прям на месте. хотя бы через параметры сделал.

собсно по просьбе на посмотреть... многа букаф. кто ж так вопросы 
задает. в вопросе должна быть отражена только суть, не больше, ни
 меньше. и только в виде доп инфы приложить урлу, где можно лицезреть 
весь код.

Deleted ()

Re: Producer <-> Consumer

Непонятно, что эта штука делает. Например, зачем cond, если нигде не делается pthread_cond_wait()? Ну да не суть. Для затравки могу сказать, что printf - это не thread-safe, им просто так в многопоточных программах нельзя пользоваться, надо синхронизировать через мьютекс, либо писать собственную thread-safe функцию вывода.

anonymous ()

Re: Producer <-> Consumer

могу помочь только советом(уж чем могу)
переведи это в модель сети Петри и ищи терминалы или как там они называются
это если не лень теорию почитать

dimon555 ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.