Solved

How to synchronize those threads?

Posted on 2001-09-06
8
1,765 Views
Last Modified: 2007-12-19
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
Comment
Question by:sandy_wu
  • 4
  • 4
8 Comments
 

Author Comment

by:sandy_wu
ID: 6459934
///////////////////////////////////
/////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
 
LVL 5

Expert Comment

by:garboua
ID: 6460692
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
 

Author Comment

by:sandy_wu
ID: 6462692
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
 
LVL 5

Accepted Solution

by:
garboua earned 100 total points
ID: 6463931
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
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

Author Comment

by:sandy_wu
ID: 6469511
hello garboua

I was a little confuse about semaphores, would U please modify the program above with semaphores ?
thank U very very much!!
0
 
LVL 5

Expert Comment

by:garboua
ID: 6470643
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
 

Author Comment

by:sandy_wu
ID: 6475879
Thank U garboua , you are so kind!
0
 
LVL 5

Expert Comment

by:garboua
ID: 6488036
U betYYYYaaaa
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Have you ever been frustrated by having to click seven times in order to retrieve a small bit of information from the web, always the same seven clicks, scrolling down and down until you reach your target? When you know the benefits of the command l…
The purpose of this article is to fix the unknown display problem in Linux Mint operating system. After installing the OS if you see Display monitor is not recognized then we can install "MESA" utilities to fix this problem or we can install additio…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now