LINUX.ORG.RU

История изменений

Исправление kto_tama, (текущая версия) :

вот пример, где с одним списком работают несколько потоков - прошу прощения за портянку:

#include	<stdio.h>
#include	<stdlib.h>
#include	<pthread.h>

#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: prodcons <#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);
}



Исправление kto_tama, :

вот пример, где с одним списком работают несколько потоков - прошу прощения за портянку:

[br]#include	<stdio.h>[br]#include	<stdlib.h>[br]#include	<pthread.h>[br][br]#define	MAXNITEMS 		1000000[br]#define	MAXNTHREADS			100[br][br]int		nitems;			[br][br]struct node* List ;[br][br]struct {[br]  pthread_mutex_t	mutex;[br]  pthread_cond_t	cond;[br]  int				nready;	[br]  int	count;[br]  long producer_sum  ;[br]  struct node* List ;[br]} put = { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER };[br][br]struct {[br]  pthread_mutex_t	mutex;[br]  pthread_cond_t	cond;[br]  int				nready;	[br]  int	count;[br]  long consumer_sum  ;[br]  struct node* List ;[br]} get = { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER };[br][br]void	*produce(void *), *consume(void *);[br]int  Length(char * name , struct node* head);[br]int  Pop(struct node** headRef);[br]void Add(struct node** headRef, int num) ;[br] [br]int main(int argc, char **argv)[br]{[br]	int			i, nthreads, count[MAXNTHREADS] , count2[MAXNTHREADS];[br]	pthread_t	tid_produce[MAXNTHREADS], tid_consume[MAXNTHREADS];[br][br]	List = NULL ;[br][br]	if (argc != 3)[br]	{[br]		printf("usage: prodcons <#items> <#threads>\n");[br]		exit(0);[br]	}[br]	nitems = atoi(argv[1]);[br]	nthreads = atoi(argv[2]);[br][br]	for (i = 0; i < nthreads; i++) [br]	{[br]		count[i] = 0;[br]		pthread_create(&tid_produce[i], NULL, produce, &count[i]);[br]		count2[i] = 0;[br]		pthread_create(&tid_consume[i], NULL, consume, &count2[i]);[br]	}[br][br]	for (i = 0; i < nthreads; i++) [br]	{[br]		pthread_join(tid_produce[i], NULL);[br]		pthread_join(tid_consume[i], NULL);[br]		printf("count[%d] = %d  count2[%d] = %d\n", i, count[i], i, count2[i]);	[br]	}[br][br]	printf("producer_sum =%d  consumer_sum =%d\n" , put.producer_sum , get.consumer_sum);  // results in len == 3[br]	printf("producer counter =%d  consumer counter =%d\n" , put.count , get.count);  // results in len == 3[br]    printf("queue length =%d\n",Length("List",List));  // results in len == 3[br][br]	exit(0);[br]}[br][br]void * produce(void *arg)[br]{[br]	for ( ; ; ) {[br]		pthread_mutex_lock(&put.mutex);[br]		if (put.count >= nitems) {[br]			pthread_mutex_unlock(&put.mutex);[br]			return(NULL);		/* array is full, we're done */[br]		}[br]		Add(&List, put.count ); [br]		put.producer_sum +=put.count;[br]		put.count++;[br]		printf("producer =%d  consumer =%d\n" , put.count , get.count);  // results in len == 3[br]		pthread_mutex_unlock(&put.mutex);[br][br]		pthread_mutex_lock(&get.mutex);[br]		if (get.nready == 0)[br]			pthread_cond_signal(&get.cond);[br]		get.nready++;[br]		pthread_mutex_unlock(&get.mutex);[br][br]		*((int *) arg) += 1;[br]	}[br]	return(NULL);		/* array is full, we're done */[br]}[br][br]void * consume(void *arg)[br]{[br]	for ( ; ; ) {[br]			pthread_mutex_lock(&get.mutex);[br]			if (get.count >= nitems ) [br]			{[br]				pthread_mutex_unlock(&get.mutex);[br]				return(NULL);		/* array is full, we're done */[br]			}[br]			if(get.count < put.count)[br]			{[br]				int queue = Pop(&List ); [br]				get.consumer_sum += queue;[br]				get.count ++;[br]				printf("producer =%d  consumer =%d\n" , put.count , get.count);  // results in len == 3[br]				*((int *) arg) += 1;[br]			}[br]			pthread_mutex_unlock(&get.mutex);[br]	[br]			pthread_mutex_lock(&put.mutex);[br]			if (put.nready == 0)[br]				pthread_cond_signal(&put.cond);[br]			put.nready++;[br]			pthread_mutex_unlock(&put.mutex);[br]	}[br]	return(NULL);[br]}[br][br][br][br][br]

Исправление kto_tama, :

вот пример, где с одним списком работают несколько потоков - прошу прощения за портянку:

[br]#include	<stdio.h>[br]#include	<stdlib.h>[br]#include	<pthread.h>[br][br]#define	MAXNITEMS 		1000000[br]#define	MAXNTHREADS			100[br][br]int		nitems;			[br][br]struct node* List ;[br][br]struct {[br]  pthread_mutex_t	mutex;[br]  pthread_cond_t	cond;[br]  int				nready;	[br]  int	count;[br]  long producer_sum  ;[br]  struct node* List ;[br]} put = { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER };[br][br]struct {[br]  pthread_mutex_t	mutex;[br]  pthread_cond_t	cond;[br]  int				nready;	[br]  int	count;[br]  long consumer_sum  ;[br]  struct node* List ;[br]} get = { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER };[br][br]void	*produce(void *), *consume(void *);[br]int  Length(char * name , struct node* head);[br]int  Pop(struct node** headRef);[br]void Add(struct node** headRef, int num) ;[br] [br]int main(int argc, char **argv)[br]{[br]	int			i, nthreads, count[MAXNTHREADS] , count2[MAXNTHREADS];[br]	pthread_t	tid_produce[MAXNTHREADS], tid_consume[MAXNTHREADS];[br][br]	List = NULL ;[br][br]	if (argc != 3)[br]	{[br]		printf("usage: prodcons <#items> <#threads>\n");[br]		exit(0);[br]	}[br]	nitems = atoi(argv[1]);[br]	nthreads = atoi(argv[2]);[br][br]	for (i = 0; i < nthreads; i++) [br]	{[br]		count[i] = 0;[br]		pthread_create(&tid_produce[i], NULL, produce, &count[i]);[br]		count2[i] = 0;[br]		pthread_create(&tid_consume[i], NULL, consume, &count2[i]);[br]	}[br][br]	for (i = 0; i < nthreads; i++) [br]	{[br]		pthread_join(tid_produce[i], NULL);[br]		pthread_join(tid_consume[i], NULL);[br]		printf("count[%d] = %d  count2[%d] = %d\n", i, count[i], i, count2[i]);	[br]	}[br][br]	printf("producer_sum =%d  consumer_sum =%d\n" , put.producer_sum , get.consumer_sum);  // results in len == 3[br]	printf("producer counter =%d  consumer counter =%d\n" , put.count , get.count);  // results in len == 3[br]    printf("queue length =%d\n",Length("List",List));  // results in len == 3[br][br]	exit(0);[br]}[br][br]void * produce(void *arg)[br]{[br]	for ( ; ; ) {[br]		pthread_mutex_lock(&put.mutex);[br]		if (put.count >= nitems) {[br]			pthread_mutex_unlock(&put.mutex);[br]			return(NULL);		/* array is full, we're done */[br]		}[br]		Add(&List, put.count ); [br]		put.producer_sum +=put.count;[br]		put.count++;[br]		printf("producer =%d  consumer =%d\n" , put.count , get.count);  // results in len == 3[br]		pthread_mutex_unlock(&put.mutex);[br][br]		pthread_mutex_lock(&get.mutex);[br]		if (get.nready == 0)[br]			pthread_cond_signal(&get.cond);[br]		get.nready++;[br]		pthread_mutex_unlock(&get.mutex);[br][br]		*((int *) arg) += 1;[br]	}[br]	return(NULL);		/* array is full, we're done */[br]}[br][br]void * consume(void *arg)[br]{[br]	for ( ; ; ) {[br]			pthread_mutex_lock(&get.mutex);[br]			if (get.count >= nitems ) [br]			{[br]				pthread_mutex_unlock(&get.mutex);[br]				return(NULL);		/* array is full, we're done */[br]			}[br]			if(get.count < put.count)[br]			{[br]				int queue = Pop(&List ); [br]				get.consumer_sum += queue;[br]				get.count ++;[br]				printf("producer =%d  consumer =%d\n" , put.count , get.count);  // results in len == 3[br]				*((int *) arg) += 1;[br]			}[br]			pthread_mutex_unlock(&get.mutex);[br]	[br]			pthread_mutex_lock(&put.mutex);[br]			if (put.nready == 0)[br]				pthread_cond_signal(&put.cond);[br]			put.nready++;[br]			pthread_mutex_unlock(&put.mutex);[br]	}[br]	return(NULL);[br]}[br][br][br][br][br]

Исправление kto_tama, :

вот пример, где с одним списком работают несколько потоков - прошу прощения за портянку:

<code>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#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: prodcons <#items> <#threads>\n»);
exit(0);
}
nitems = atoi(argv[1]);
nthreads = atoi(argv[2]);

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

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

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);
}




</code>

Исходная версия kto_tama, :

вот пример, где с одним списком работают несколько потоков - прошу прощения за портянку:

<code class=«cpp»>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#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: prodcons <#items> <#threads>\n»);
exit(0);
}
nitems = atoi(argv[1]);
nthreads = atoi(argv[2]);

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

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

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);
}




</code>