From owner-freebsd-hackers@FreeBSD.ORG Mon Jun 27 18:26:14 2005 Return-Path: X-Original-To: freebsd-hackers@freebsd.org Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id CFFF016A41C for ; Mon, 27 Jun 2005 18:26:14 +0000 (GMT) (envelope-from jhb@FreeBSD.org) Received: from mv.twc.weather.com (mv.twc.weather.com [65.212.71.225]) by mx1.FreeBSD.org (Postfix) with ESMTP id 6E6F843D1F for ; Mon, 27 Jun 2005 18:26:14 +0000 (GMT) (envelope-from jhb@FreeBSD.org) Received: from [10.50.41.231] (Not Verified[65.202.103.25]) by mv.twc.weather.com with NetIQ MailMarshal (v6, 0, 3, 8) id ; Mon, 27 Jun 2005 14:39:53 -0400 From: John Baldwin To: freebsd-hackers@freebsd.org, Pablo Mora Date: Mon, 27 Jun 2005 13:18:35 -0400 User-Agent: KMail/1.8 References: In-Reply-To: MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200506271318.36748.jhb@FreeBSD.org> Cc: Subject: Re: problem handling POSIX thread on FreeBSD X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 27 Jun 2005 18:26:14 -0000 On Monday 27 June 2005 01:32 am, Pablo Mora wrote: > /* file: test.c */ > #include > #include > #include > #include > #include > > char buffer[512]; > pthread_mutex_t mutex, mutex2; > pthread_t hilo1, hilo2; > > void f1(void* ptr) > { > int i,n=10; > int valor=0; > char*p=(char*)ptr; > > for(i=0;i { > pthread_mutex_lock(&mutex); > sscanf(p,"%d",&valor); > printf("\thilo1: puntero contiene %d\n", valor); > valor=i*3; > sprintf(p, "%d",valor); > > pthread_mutex_unlock(&mutex2); > } > valor=(int)pthread_self(); > printf("finaliza hilo1 con id %d\n", valor); > pthread_exit(&valor); > } > void f2(void* ptr) > { > int i,n=10; > int valor=0; > char*p=(char*)ptr; > for(i=0;i { > pthread_mutex_lock(&mutex2); > sscanf(p,"%d",&valor); > printf("hilo2: puntero contiene %d\n", valor); > valor=i*2; > > sprintf(p, "%d",valor); > pthread_mutex_unlock(&mutex); > } > valor=(int)pthread_self(); > printf("finaliza hilo2 con id %d\n", valor); > pthread_exit(&valor); > } This code is nuts. You can't unlock a mutex that you don't own. You probably want to be using semaphores I think. However, even then that doesn't really make sense. Replace 'mutex2' with 'mutex' in the f1() and f2() functions and get rid of mutex2 and try it again. However, with that change, f1() is free to run to completion before f2() will start. If you want to enforce ping ponging, you need to use a condition variable to synchronize. Something like: pthread_cond_t condvar; f1() { ... pthread_mutex_lock(&mutex); for (i = 0; i < n; i++) { sscanf(...) printf(...) valor = i * 3; sprintf(...) pthread_cond_wait(&condvar, &mutex); } pthread_mutex_unlock(&mutex); valor = (int)pthread_self(); ... } and f2() is similar except s/3/2/. This will cause the threads to ping pong where one thread waits for the other to run after each cycle. You might also want to read up on how synchronization with multiple threads works. "Programming with POSIX Threads" is a decent book, and Tannebaum's "Modern Operating Systems" has a decent section on various synchronization primitives such as mutexes, semaphores, etc. Also, if you have thread specific questions, there is a freebsd-threads@ mailing list that is probably a better place to ask them on. > int main() > { > pthread_attr_t atributos; > //pthread_mutexattr_t mutexattr; - solaris > > memset(buffer, '\0', sizeof(buffer)); > /* > > if(pthread_mutexattr_setpshared(&mutexattr,PTHREAD_PROCESS_PRIVATE)!=0) > //solaris > { > perror("pthread_mutexattr_setpshared"); > exit(-12); > } > */ > > pthread_mutex_init(&mutex, NULL); //linux > pthread_mutex_init(&mutex2, NULL); //linux > > pthread_mutex_lock(&mutex2); / > > /*if(pthread_mutex_init(&mutex, &mutexattr)!=0) //solaris > { > perror("pthread_mutex_init"); > exit(-2); > }*/ > > if(pthread_attr_init(&atributos) < 0) > { > perror("pthread_attr_init"); > exit(-1); > } > if(pthread_attr_setscope(&atributos,PTHREAD_SCOPE_PROCESS) < 0) > { > perror("pthread_attr_setscope"); > exit(-2); > } > if(pthread_create (&hilo1, &atributos, (void*)&f1, (void*)buffer)<0) > { > perror("pthread_create hilo1"); > exit(-2); > } > if(pthread_create(&hilo2, &atributos, (void*)&f2, (void*)buffer)<0) > { > perror("pthread_create hilo2"); > exit(-2); > } > > > if(pthread_join(hilo2, NULL)<0) > { > perror("pthread_join hilo1 "); > exit(-3); > } > puts("fin hilo 2"); > /*if(pthread_join(hilo1, NULL)<0) > { > perror("pthread_join hilo2 "); > exit(-3); > }*/ > > > pthread_mutex_destroy(&mutex); > exit(0); > } > > output in solaris and linux: (gcc test.c -lpthread) > > hilo1: puntero contiene 0 > hilo2: puntero contiene 0 > hilo1: puntero contiene 0 > hilo2: puntero contiene 3 > hilo1: puntero contiene 2 > hilo2: puntero contiene 6 > hilo1: puntero contiene 4 > hilo2: puntero contiene 9 > hilo1: puntero contiene 6 > hilo2: puntero contiene 12 > hilo1: puntero contiene 8 > hilo2: puntero contiene 15 > hilo1: puntero contiene 10 > hilo2: puntero contiene 18 > hilo1: puntero contiene 12 > hilo2: puntero contiene 21 > hilo1: puntero contiene 14 > hilo2: puntero contiene 24 > hilo1: puntero contiene 16 > finaliza hilo1 con id 1082231728 > hilo2: puntero contiene 27 > finaliza hilo2 con id 1090624432 > fin hilo 2 > > output on FreeBSD v4.11 STABLE (gcc test.c -pthread): > > hilo1: puntero contiene 0 > hilo1: puntero contiene 0 > hilo1: puntero contiene 3 > hilo1: puntero contiene 6 > hilo1: puntero contiene 9 > hilo1: puntero contiene 12 > hilo1: puntero contiene 15 > hilo1: puntero contiene 18 > hilo1: puntero contiene 21 > hilo1: puntero contiene 24 > finaliza hilo1 con id 134534144 > > why ?? > > help me please :-). -- John Baldwin <>< http://www.FreeBSD.org/~jhb/ "Power Users Use the Power to Serve" = http://www.FreeBSD.org