Re: problem handling POSIX thread on FreeBSD

From: John Baldwin (jhb_at_FreeBSD.org)
Date: 06/27/05

  • Next message: Niki Denev: "Re: How to disable at-boot configuration of a network interface but permit manual use of rc.d?"
    To: freebsd-hackers@freebsd.org, Pablo Mora <fbsd.hackers@gmail.com>
    Date: Mon, 27 Jun 2005 13:18:35 -0400
    
    

    On Monday 27 June 2005 01:32 am, Pablo Mora wrote:
    > /* file: test.c */
    > #include<stdio.h>
    > #include<pthread.h>
    > #include<string.h>
    > #include<unistd.h>
    > #include<stdlib.h>
    >
    > 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<n;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<n;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 <jhb@FreeBSD.org>  <><  http://www.FreeBSD.org/~jhb/
    "Power Users Use the Power to Serve"  =  http://www.FreeBSD.org
    _______________________________________________
    freebsd-hackers@freebsd.org mailing list
    http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
    To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.org"
    

  • Next message: Niki Denev: "Re: How to disable at-boot configuration of a network interface but permit manual use of rc.d?"

    Relevant Pages

    • Re: (void**)&ppval
      ... a sort of "generic data pointer type". ... returned from mallochas type "void *", so that it can point to ... void *tmp; ... T *ptr; ...
      (comp.lang.c)
    • Re: warning C4238 : cast reference in void*
      ... void* foo ... why void* ptr = &foo2give this warning? ... Do you understand what rvalue and lvalue mean? ...
      (microsoft.public.vc.language)
    • Re: incrementing void *
      ... void *ptr; ... Which of the following is the correct way to increment the variable ... Its a void * pointer. ... then they want you to treat ptr as if it were a myStruct * ...
      (comp.lang.c)
    • Re: A new Critical Section for high contention situations
      ... void enter ... You said "there is no synchroniztion", then, what does synchronization ... You said "there is no contention", ... You mentioned "race conditions" but, ...
      (microsoft.public.win32.programmer.kernel)
    • Re: recasting a pointer
      ... Conversion from void * to any other object pointer type is ... In the assignment statement that I commented out, ptr is converted ...
      (comp.lang.c)

    Loading