[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1791
  • Last Modified:

How to synchronize those threads?

I write a programmer, what i want is :

1. read threads(getdata() and printdata()) can run  concurrent when there is no thread deldata or adddata.
2. there is only one modify thread running (deldata or adddata) at same time.
3. emptydata must be call at last!

this programmer run not correctly, the data before operation should equal to the data after operation! but here, whatever i use macro SEM or not, the result is not equal why?

the programmer below is not effective, when there is one thread getdata, other threads cant getdata. and how to call emptydata safely??

does linux has this thread sleep function? it should not use process sleep()when empty all data!


////////////////////////////////
//////test.cpp part 1
////////////////////////////////


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

#define SEM

void getdata();
void adddata(void*para);
void deldata(void*para);
void printdata();
void emptydata();


#ifdef SEM
pthread_mutex_t mutex;
#endif

struct id{
     char*uid;
     id*next;
};


class testVector{
private:
     id*header;
public:
     id* getHeader()
     {
          return header;
     }
     
     bool add(char *uid)
     {
          id *p1=new id;
          if (!p1) return false;

          p1->uid =new char[strlen(uid)+1];
          strcpy(p1->uid,uid);

          if(header==NULL) header=p1;
          else{
               p1->next=header->next;
               header->next=p1;
          }
          return true;
     }
     bool del(char *uid)
     {
          id *p1=header,*p2=NULL;
          while(p1!=NULL){
               if(!strcmp(uid,p1->uid)){//found;
                    if(p2!=NULL){//p1 is not header
                         p2->next=p1->next;
                    }
                    else{//p1 is header;
                         header=p1->next;
                    }
                    delete(p1);
                    return true;
               }
               p2=p1;p1=p1->next;
          }
          return false;//user
     }
     void emptydata()
     {
          id *p1=header,*p2=NULL;
          while(p1!=NULL){
               p2 = p1;
               p1=p1->next;
               delete(p2);
          }
     }
};


0
sandy_wu
Asked:
sandy_wu
  • 4
  • 4
1 Solution
 
sandy_wuAuthor Commented:
///////////////////////////////////
/////test.cpp part 2
///////////////////////////////////
testVector v;
struct timespec delay;


int main()
{
     
     char uid[100];
     
#ifdef SEM
     pthread_mutex_init(&mutex,NULL);
#endif

     delay.tv_sec = 2;
     delay.tv_nsec = 0;
     
     for (int i = -100; i<=-1; i++)
     {
          sprintf(uid,"_________________________________%d",i);
          if (!v.add(uid))
               printf("add date failed when init %d",i);
     }
     
     printf("*************  before  *************\n");
     printdata();

     for (int i = 1; i<=10000; i++)
     {
         
          pthread_t thread1, thread2,thread3,thread4;
          pthread_attr_t attr1,attr2,attr3,attr4;

          sprintf(uid,"_________________________________%d",i);

          pthread_attr_init(&attr1);
          pthread_attr_setdetachstate(&attr1,PTHREAD_CREATE_DETACHED);

          pthread_attr_init(&attr2);
          pthread_attr_setdetachstate(&attr2,PTHREAD_CREATE_DETACHED);

          pthread_attr_init(&attr3);
          pthread_attr_setdetachstate(&attr3,PTHREAD_CREATE_DETACHED);
         
          pthread_attr_init(&attr4);
          pthread_attr_setdetachstate(&attr4,PTHREAD_CREATE_DETACHED);

          pthread_create(&thread1, &attr1,
               (void *) &adddata, uid);
                   
          pthread_create(&thread2, &attr2,
               (void *) &getdata, NULL);
         
          pthread_create(&thread3, &attr3,
               (void *) &deldata, uid);
         
          pthread_create(&thread4, &attr4,
               (void *) &getdata, NULL);
     }    


#ifdef SEM
     pthread_mutex_lock(&mutex);
     pthread_mutex_unlock(&mutex);
     pthread_mutex_destroy(&mutex);
#endif
//     pthread_delay_np(&delay); //does linux has this function? it should not use sleep()
     sleep(1);
     printf("*************  after  *************\n");
     printdata();
     emptydata();
}

void emptydata()
{
     v.emptydata();
}
void getdata()
{
     
#ifdef SEM
     pthread_mutex_lock(&mutex);
#endif
     id * h;
     h = v.getHeader();
     while (h)
     {
          h=h->next;
     }
#ifdef SEM
     pthread_mutex_unlock(&mutex);
#endif
     pthread_exit(NULL);    
}

void printdata()
{
     
#ifdef SEM
     pthread_mutex_lock(&mutex);
#endif
     id * h;
     h = v.getHeader();
     while (h)
     {
          printf("uid = %s\n",h->uid);
          h=h->next;
     }
#ifdef SEM
     pthread_mutex_unlock(&mutex);
#endif
}


void adddata(void*para)
{
#ifdef SEM
     pthread_mutex_lock(&mutex);
#endif
     
     char *uid;
     uid = (char *)para;
     if (!v.add(uid))
          printf("add failed %s\n",uid);
//     else
//          printf("add succeed %s\n",uid);
#ifdef SEM
     pthread_mutex_unlock(&mutex);
#endif
     pthread_exit(NULL);    
}

void deldata(void*para)
{
#ifdef SEM
     pthread_mutex_lock(&mutex);
#endif
     char *uid;
     uid = (char *)para;
     if(!v.del(uid))
          printf("del failed %s\n",uid);
//     else
//          printf("del succeed %s\n",uid);
     
#ifdef SEM
     pthread_mutex_unlock(&mutex);
#endif
     pthread_exit(NULL);    
}

0
 
garbouaCommented:
well without spending too much time on it.  
1.  why are you creating 10000 thread?
2.  you know if you declare your class function as static void and make it either protected or public, you can launch it from within, or outside and eliminate the global class declaration.
static void* emptydata(void*);
and when you launch it simply give it pthread_create(&threadID,emptydata,attr,this)
3. pthread_delay_np is not available, you can either use usleep(microseconds), go to sourceforge and download a timer class, or you can use scheduling.
I would suggest using semaphores. you can use sem_timedwait.
check out these refrences regarding semaphores and their usage
Semaphore:
http://docs.linux.cz/c_marshall/node26.html#SECTION002600000000000000000
pthread:
http://centaurus.cs.umass.edu/~wagner/threads_html/tutorial.html


0
 
sandy_wuAuthor Commented:
Thank U garboua!

1. creating 10000 thread just for test
2. but it seems not a OO style, is it?
3. does sleep() or usleep() will sleep all threads in the same process? I read this from a book, he said so and sugguest pthread_delay_np().


I think your are right, this program should use semaphores!
thanks U very much!

0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
garbouaCommented:
semaphores are very easy to use and it will sync all your threads, it is like a traffic light.  
sleep and usleep will put them to sleep.  depending on how fast you want your process to run, usleep is more like it, 25 mils for each thread
check out  sched.h it will actually let you use a priority for threads if you are using parrallel threads, or as i mentioned semaphores are cool.
0
 
sandy_wuAuthor Commented:
hello garboua

I was a little confuse about semaphores, would U please modify the program above with semaphores ?
thank U very very much!!
0
 
garbouaCommented:
weeeeeeeeeeeeeeeeeeel, this might take a while sandy.  I can just slap it on here, but it will make no sense.
1.  why are you using this little link list?  use standard lib  list

do this
list<char*>mycharacterPointerLinkList; //maybe a shorter name
list<char*>::iterator ptr;
and from here on you can use
 characterPointerLinkList.push_front(char*)
 characterPointerLinkList.push_back(char*)  
to insert you data all day long
to pull the data out, you can loop through the link list with the iterator.
for (ptr==characterPointerLinkList.begin(); ptr!=characterPointerLinkList.end();++ptr)
// here you can do somthing with ptr,  you can delete it, you can sort link list, you can modify ptr, whatever you want from this point on.

to use semaphore with an example,   look at this
lets say you have three threads, delete daemon, add daemon, and process daemon.

declare

sem_t   delDaemon, addDeamon, procDeamon;
void* deleteDaemon(void*);
void* addsDaemon(void*);
void*processDaemon(void*);

/* this is main*/
int main()
{
sem_init (&delDaemon,NO_SHARE,1);
sem_init(&addDemon,NO_SHARE,0);
sem_init(&procsDaemon,NO_SHARE,0);/* now you want process to wait on add, and add to wait on delete and delete to wait on process  */
pthread_create(you know how to create threads already, all 3 with whatever args);
pthread_join(idofThreadOne,NULL); /*wait for all threads*/
}

/*now  you do the how now brown cow stuff */
void* deleteDaemon(void* arg)
{
  int *some=(int*)arg; /* or whatever the argument passed is */
 while (1)
{
  /* wait for process daemon */
sem_wait(&procsDaemon);
/* we are here, which means  process daemon finished processing loop instance */
do_something();
sem_post(&addDaemon); /* tell add daemon we are done*/
}
return arg;
}
 void* addsDaemon(void* arg)
{
  while (1)
{
 sem_wait(&delDaemon);
/* for more option do "man sem_wait"*/
add_something();
sem_post(&procsDaemon);
}
return arg;
}


You got the idea  of the semaphore.  it works like a scheduler.


C++ --> sample daemons
class bogusClass{
 private:
;;;;
;;;;
;;;;
;;;
;;;
protected:
static void * sampleDaemon(void*arg)
{
 bogusClass* me =(bogusClass*)arg;
  // now you can access all variables and function provate and public of this class with (me)
  while (me->condition)
{
 do punch of things();
}
}
public:
constructor and destructor
void entryPoint()
{
 here is where you launch your daemons, all nad one.
pthread_create(&threadId, NULL, sampleDaemon, this);
// and all the rest of your daemons//
// now you simple exit and all you daemons are running until you terminate or main program exists, or class destructs
return;
}
};

void main()
{
 bogusClass myclass;
myclass.entryPoint();
return;
}
 le me know if you need more help

0
 
sandy_wuAuthor Commented:
Thank U garboua , you are so kind!
0
 
garbouaCommented:
U betYYYYaaaa
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 4
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now