0
  1. General Question: I can't understand the mechanism of POSIX threads in Linux. Some specific questions would be asked under the code block.

  2. Description: I call two sub-threads in my main thread. One is Producer, the other is Consumer. But my program always run as like it that Producers do all the work, then Consumer run. When I add a sleeptime, it changes.

Here's the main code:

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<pthread.h>
#include<unistd.h>
#include<signal.h>
#include<semaphore.h>
#define Maxbuf 100
#define TimeOfOp 100
#define true 1
#define false 0
//data structure 
struct CircleBuf
{
    int read;
    int write;
    int buf[Maxbuf];
}  circlebuf;

sem_t mutex;
sem_t empty;
sem_t full;

void writeCircleBuf(struct CircleBuf *circlebuf,int *value){//  =  v
    circlebuf->buf[circlebuf->write]=(*value);
    circlebuf->write=(circlebuf->write+1)%Maxbuf;
}

int readCircleBuf(struct CircleBuf *circlebuf){// =  p
    int value=0;
    value=circlebuf->buf[circlebuf->read];
    circlebuf->buf[circlebuf->read]=0;// reset buf[read]=0
    circlebuf->read=(circlebuf->read+1)%Maxbuf;
    return value;
}

void OutCirclebuf(struct CircleBuf *circlebuf){
    int i;
    printf("******************the size in each buffer:");
        for(int i=0;i<Maxbuf;i++){
        printf("%d ",circlebuf->buf[i]);
    }
    printf("\n\n");
}

void sign(int sig){
    exit(0);
}

void* productThread(void *i){//producer thread
    int *n=(int *)i;//thread id
    int t=TimeOfOp;
    while(t--){
    sem_wait(&empty);//sem_t empty -1
    sem_wait(&mutex);//sem_t mutex -1
    writeCircleBuf(&circlebuf,n);//put thread id into buffer
    printf("++++++++++++++++++producer %d put value=%d into buffer.\n",*n,*n);
    sem_post(&mutex);
    sem_post(&full);
    //usleep(50000);
    }
}

void * consumerThread(void *i){
    int *n=(int*)i;//thread id
    int value=0;
    int t=TimeOfOp;
    while(t--){
        sem_wait(&full);
        sem_wait(&mutex);
        value=readCircleBuf(&circlebuf);
        printf("-----------------consumer %d take value=%d ouf buffer.\n",*n,value);

//  OutCirclebuf(&circlebuf);
    sem_post(&mutex);
    sem_post(&empty);
   // usleep(50000);
    }
}

int main(){
    int i;
    pthread_t cpid,ppid; 
    sem_init(&mutex,0,1);//mutex init 1 
    sem_init(&empty,0,Maxbuf);
    sem_init(&full,0,0);

    signal(SIGINT,sign);
    signal(SIGTERM,sign);
    circlebuf.read=circlebuf.write=0;
    for(int i=0;i<Maxbuf;i++) circlebuf.buf[i]=0;
    int id=1;
    pthread_create(&ppid,NULL,productThread,(void*)&id);
    pthread_create(&cpid,NULL,consumerThread,(void*)&id);
    pthread_join(cpid,NULL);
    pthread_join(ppid,NULL);
    sem_destroy(&mutex);
    sem_destroy(&empty);
    sem_destroy(&full);
    pthread_exit(NULL);
    return 0;
}

Specific Questions:

  1. Why is there no difference when I change the sequence of pthread_create(&ppid,NULL,productThread,(void*)&id); and pthread_create(&cpid,NULL,consumerThread,(void*)&id); these two create sequence?

  2. Is it possible that the computer runs so fast, not until one thread calls another thread up, it has done all the work? So, I add a sleep function, the result changes to Alternate Operation. But when I add it to different places it has different effects, I was confused.

Please guide me. Thanks.

Azeem
  • 11,148
  • 4
  • 27
  • 40
Victor
  • 23
  • 4
  • The `sem_t` structure is an [*opaque data type*](https://en.wikipedia.org/wiki/Opaque_data_type). You should not mess about with the data it might contain. Especially a field such as `__align` which seems to be a dummy field to add some alignment. You should not even *read* the members, unless any specification says it's okay (which [the POSIX specification](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/semaphore.h.html) doesn't). – Some programmer dude Nov 27 '17 at 04:16
  • Furthermore, your first question is to broad. That's what text-books and teachers are for. – Some programmer dude Nov 27 '17 at 04:16
  • Seems like you might be over-running your circular buffer. I don't see any checking to see it it has space, or whether it accepted your write. So your producer very well may "finish" running before your consumer ever starts...but only because it throws it's writes away. – lockcmpxchg8b Nov 27 '17 at 04:26
  • 2 yes this is probably what happens, why do you expect anything else? – n. m. could be an AI Nov 27 '17 at 07:38

0 Answers0