代码之家  ›  专栏  ›  技术社区  ›  KateMak

使线程循环5次;pthreads、互斥和信号量

  •  -2
  • KateMak  · 技术社区  · 12 年前

    我在课堂上的一个例子中有这段代码,老师的指示说“让每个线程循环5次”。我对如何做到这一点感到困惑,因为有了这个代码:

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <semaphore.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <iostream>
    #include <iomanip>
    #include <sstream>
    #include <sys/utsname.h>
    
    /* Symbolic Constants*/
    #define NUM_THREADS 4
    #define BUFFER_SIZE 10
    
    /* Semaphore and Mutex lock */
    sem_t cEmpty;
    sem_t cFull;
    pthread_mutex_t mutex;
    
    /* Threads */
    pthread_t tid; /* Thread ID */
    pthread_attr_t attr; /* Thread attributes */
    
    //prototypes
    void *producer(void *param);
    void *consumer(void *param);
    int insert_item(int threadID);
    int remove_item(int threadID);
    void init();
    
    /* Progress Counter and Thread IDs*/
    int counter, pthreadID=0, cthreadID=0;
    
    int main()
    {
      /* Variables */
      int c1;
    
      /* Perform initialization */
      init();
    
      /* Create the producer threads */
      for(c1=0; c1<NUM_THREADS; c1++)
      {
        pthread_create(&tid, &attr, producer, NULL);
      }
    
      /* Create the consumer threads */
      for(c1=0; c1<NUM_THREADS; c1++)
      {
        pthread_create(&tid, &attr, consumer, NULL);
      }
    
      /* Ending it */
      sleep(2);
    
      printf("All threads are done.\n");
    
      /* Destroy the mutex and semaphors */
      pthread_mutex_destroy(&mutex);
      sem_destroy(&cEmpty);
      sem_destroy(&cFull);
    
      printf("Resources cleaned up.\n");
    
      exit(0);
    }
    
    void init()
    {
      pthread_mutex_init(&mutex, NULL); /* Initialize mutex lock */
      pthread_attr_init(&attr); /* Initialize pthread attributes to default */
      sem_init(&cFull, 0, 0); /* Initialize full semaphore */
      sem_init(&cEmpty, 0, BUFFER_SIZE); /* Initialize empty semaphore */
      counter = 0; /* Initialize global counter */
    }
    
    void *producer(void *param)
    {
      int x;
      for(x=0; x<5;)
      {
        sleep(1);
    
        sem_wait(&cEmpty); /* Lock empty semaphore if not zero */
        pthread_mutex_lock(&mutex);
    
        if(insert_item(pthreadID))
        {
          fprintf(stderr, "Producer error.");
        }
        else
        {
          pthreadID++;
          x++;
        }
    
        pthread_mutex_unlock(&mutex);
        sem_post(&cFull); /* Increment semaphore for # of full */
      }
    return 0;
    }
    
    void *consumer(void *param)
    {
      int y;
      for(y=0; y<5;)
      {
        sleep(1);
    
        sem_wait(&cFull); /* Lock empty semaphore if not zero */
        pthread_mutex_lock(&mutex);
    
        if(remove_item(cthreadID))
        {
          fprintf(stderr, "Consumer error.");
        }
        else
        {
          cthreadID++;
          y++;
        }
        pthread_mutex_unlock(&mutex);
        sem_post(&cEmpty); /* Increments semaphore for # of empty */
      }
    return 0;
    }
    
    int insert_item(int threadID)
    {
      if(counter < BUFFER_SIZE) /* Buffer has space */
      {
        counter++;
        printf("Producer %d inserted a cookie. Total:%d\n", threadID, counter);
        return 0;
      }
      else /* Buffer full */
      {
        return -1;
      }
    }
    
    int remove_item(int threadID)
    {
      if(counter > 0) /* Buffer has something in it */
      {
        counter--;
        printf("Consumer %d removed a cookie. Total:%d\n", threadID, counter);
        return 0;
      }
      else /* Buffer empty */
      {
        return -1;
      }
    }
    

    有人知道我在哪里添加for循环以“使每个线程循环5次”吗?提前非常感谢。

    更新:我用5次迭代将while(1)更改为for循环,但我仍然无法从insert_item和remove_item函数中获得打印5次的消息,这是唯一一次打印。有人知道我怎么才能把它打印5次吗?

    1 回复  |  直到 12 年前
        1
  •  0
  •   KateMak    12 年前

    问题是,在main结束时,我称之为sleep(2)。这还不够所有线程打印输出的时间。我也没有将正确的索引传递给add_item和remove_item函数。此外,我需要一个用于所有线程的join命令,而不是sleep命令,join命令确保所有线程在程序退出之前完成。这是更新和更正的代码。希望这能帮助到尝试做类似事情的人!

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <semaphore.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <iostream>
    #include <iomanip>
    #include <sstream>
    #include <sys/utsname.h>
    
    // Symbolic Constants
    #define NUM_THREADS 4
    #define BUFFER_SIZE 10
    
    // Semaphore and Mutex lock
    sem_t cEmpty;
    sem_t cFull;
    pthread_mutex_t mutex;
    
    // Threads
    pthread_t tid[NUM_THREADS]; //Thread ID
    pthread_t tid2[NUM_THREADS]; //Thread ID
    pthread_attr_t attr; //Thread attributes
    
    //prototypes
    void *producer(void *param);
    void *consumer(void *param);
    int insert_item(long threadID);
    int remove_item(long threadID);
    void init();
    
    //Progress Counter and Thread IDs
    int counter=0;
    
    int main()
    {
      //Variables
      long c1;
    
      //Perform initialization
      init();
    
      //Create the producer threads
      for(c1=0; c1<NUM_THREADS; c1++)
      {
        pthread_create(&tid[c1], &attr, producer, (void *)c1);
        pthread_create(&tid2[c1], &attr, consumer, (void *)c1);
      }
    
      //Ending it
      for(c1=0; c1<NUM_THREADS; c1++)
      {
        pthread_join(tid[c1], NULL);
        pthread_join(tid2[c1],NULL);
      }
    
      printf("All threads are done.\n");
    
      //Destroy the mutex and semaphors
      pthread_mutex_destroy(&mutex);
      sem_destroy(&cEmpty);
      sem_destroy(&cFull);
    
      printf("Resources cleaned up.\n");
    
      exit(0);
    }
    
    //This function performs initialization
    void init()
    {
      pthread_mutex_init(&mutex, NULL); //Initialize mutex lock
      pthread_attr_init(&attr); //Initialize pthread attributes to default
      sem_init(&cFull, 0, 0); //Initialize full semaphore
      sem_init(&cEmpty, 0, BUFFER_SIZE); //Initialize empty semaphore
      counter = 0; //Initialize global counter
    }
    
    //This function creates the producer thread
    void *producer(void *param)
    {
      long index = (long)param;
    
      for(int x = 0; x<5; x++)
      {
        sleep(1);
    
        sem_wait(&cEmpty); //Lock empty semaphore if not zero
        pthread_mutex_lock(&mutex);
    
        //check to see if item inserted correctly; print error on fail
        if(insert_item(index))
        {
          fprintf(stderr, "Producer error.");
        }
    
        pthread_mutex_unlock(&mutex);
        sem_post(&cFull); //Increment semaphore for # of full
      }
    pthread_exit(NULL);
    return 0;
    }
    
    //This function created the consumer thread
    void *consumer(void *param)
    {
      long index = (long)param;
    
      for(int x = 0; x<5; x++)
      {
        sleep(1);
    
        sem_wait(&cFull); //Lock empty semaphore if not zero
        pthread_mutex_lock(&mutex);
    
        //print error if cookie not decremented correctly
        if(remove_item(index))
        {
          fprintf(stderr, "Consumer error.");
        }
    
        pthread_mutex_unlock(&mutex);
        sem_post(&cEmpty); //Increments semaphore for # of empty
      }
    pthread_exit(NULL);
    return 0;
    }
    //Insert item function to increment the cookie count and print thread message
    int insert_item(long threadID)
    {
      if(counter < BUFFER_SIZE) //Buffer has space
      {
        counter++;
        printf("Producer %ld inserted a cookie. Total:%d\n", threadID, counter);
        return 0;
      }
      else //Buffer full
      {
        return -1;
      }
    }
    
    //Remove item function to decrement the cookie count and print thread message
    int remove_item(long threadID)
    {
      if(counter > 0) //Buffer has something in it
      {
        counter--;
        printf("Consumer %ld removed a cookie. Total:%d\n", threadID, counter);
        return 0;
      }
      else //Buffer empty
      {
        return -1;
      }
    }
    
    推荐文章