在哪里放置pthread互斥锁和con var以确保所有功能都被激活?

时间:2018-02-16 16:45:46

标签: c++ pthreads mutex

我有以下程序应该接受"命令"并同步处理它们。我认为大部分都有效,但是关键区域4在放置所有订单之前都没有获得互斥锁。应该在哪里放置cond_vars,以便区域4在订单仍在生成时获得锁定?

#include <pthread.h>
#include <iostream>
#include <unistd.h>
#include <cstdlib>

using namespace std;

#define MAX 10
#define N 4

// Data structure to represent a simplified Order 
// that has an order number and an item number.
struct Order
{
  int order_num;
  int item_num; 
};

Order new_orders [N];       // array of elements of type Order to be used as 
a shared buffer
int num_new_orders = 0;     // count of number of new (i.e., unprocessed)   
orders
int order_num = 0;          // global variable used to generate unique order  
numbers


pthread_mutex_t data_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t console_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t spaceAvailabe = PTHREAD_COND_INITIALIZER;
pthread_cond_t newOrder = PTHREAD_COND_INITIALIZER;
pthread_cond_t consoleVar = PTHREAD_COND_INITIALIZER;

void* takeOrders(void* arg)
{
  int item;
  int index = 0;

  for(int i = 0; i < MAX; ++i) {
    // Beginning of critical region 1
    pthread_mutex_lock(&console_mutex);

    // Get user input
    cout << "Enter a menu item number between 1 and 50: ";
    cin >> item;
    // Print new order's details
    cout << "Got new order! Order number is " << order_num <<
                " and item number: " << item << std::endl;


    // End of critical region 1
    pthread_mutex_unlock(&console_mutex);

    // Beginning of critical region 2
    pthread_mutex_lock(&data_mutex);

    // Put new order into new orders buffer and update number of new orders
    while(num_new_orders>=MAX){
        pthread_cond_wait(&spaceAvailabe, &console_mutex);
    }

    new_orders[index].order_num = order_num;
    new_orders[index++].item_num = item;
    ++num_new_orders;
    pthread_cond_signal(&newOrder);

    // End of critical region 2
     pthread_mutex_unlock(&data_mutex);

    // Update order number so that next order gets a different number
    ++order_num;


    // If the end of the new orders buffer is reached, wrap back around
    if(index == N)
        index = 0;
}

pthread_exit(NULL);
}

void* processOrders(void* arg)
{
  int item;
  int index = 0;
  int o_num;

for(int i = 0; i < MAX; ++i) {
    // Beginning of critical region 3
    pthread_mutex_lock(&data_mutex);

    // Retrieve new order details from buffer and update number of new orders

   while(num_new_orders==0)
    {
        pthread_cond_wait(&newOrder, &data_mutex);  
    }

    o_num = new_orders[index].order_num;
    item = new_orders[index++].item_num;
    --num_new_orders;
    pthread_cond_signal(&spaceAvailabe);


    // End of critical region 3
    pthread_mutex_unlock(&data_mutex);

    // Beginning of critical region 4
    pthread_mutex_lock(&console_mutex);

     // Print retrieved order's details
    cout << "Processing order number " << o_num << " with item number: " << 
item << std::endl;

    // End of critical region 4
    pthread_mutex_unlock(&console_mutex);

    // Suspend self for 1 second
    sleep(1);

    // If the end of the new orders buffer is reached, wrap back around
    if(index == N)
        index = 0;
  }
  pthread_exit(NULL);
}

int main()
{
  // Create threads to take and process orders
  pthread_t id1, id2;
  pthread_create(&id1, NULL, processOrders, NULL);
  pthread_create(&id2, NULL, takeOrders, NULL);

  pthread_join(id1, NULL);
  pthread_join(id2, NULL);

  // Print goodbye message
  cout << "Phew! Done with orders for today!" << endl;

  pthread_exit(NULL);
}

1 个答案:

答案 0 :(得分:0)

几个月前我写了一个程序How to execute thread in sync order。我在这里发布了相同的程序。这对你有帮助。另请注意,请勿将C++代码与C混合使用。更好地使用stdio.h代替iostream。在C++ 11中,线程的实现比C更容易。

pthread_cond_t cond1 = PTHREAD_COND_INITIALIZER;
pthread_cond_t cond2 = PTHREAD_COND_INITIALIZER;
pthread_cond_t cond3 = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t lock2 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t lock3 = PTHREAD_MUTEX_INITIALIZER;

int TRUE = 1;

void print(char *p)
{
  printf("%s",p);
}

void * threadMethod1(void *arg)
{
  printf("In thread1\n");
  do{
    pthread_mutex_lock(&lock1);
    pthread_cond_wait(&cond1, &lock1);
    print("I am thread 1st\n");
    pthread_cond_signal(&cond3);/* Now allow 3rd thread to process */
    pthread_mutex_unlock(&lock1);
  }while(TRUE);
  pthread_exit(NULL);
}

void * threadMethod2(void *arg)
{
  printf("In thread2\n");
  do
  {
    pthread_mutex_lock(&lock2);
    pthread_cond_wait(&cond2, &lock2);
    print("I am thread 2nd\n");
    pthread_cond_signal(&cond1);
    pthread_mutex_unlock(&lock2);
  }while(TRUE);
  pthread_exit(NULL);
}

void * threadMethod3(void *arg)
{
  printf("In thread3\n");
  do
  {
    pthread_mutex_lock(&lock3);
    pthread_cond_wait(&cond3, &lock3);
    print("I am thread 3rd\n");
    pthread_cond_signal(&cond2);
    pthread_mutex_unlock(&lock3);
  }while(TRUE);
  pthread_exit(NULL);
}

int main(void)
{
  pthread_t tid1, tid2, tid3;
  int i = 0;

  printf("Before creating the threads\n");
  if( pthread_create(&tid1, NULL, threadMethod1, NULL) != 0 )
        printf("Failed to create thread1\n");
  if( pthread_create(&tid2, NULL, threadMethod2, NULL) != 0 )
        printf("Failed to create thread2\n");
  if( pthread_create(&tid3, NULL, threadMethod3, NULL) != 0 )
        printf("Failed to create thread3\n");
  pthread_cond_signal(&cond1);/* Now allow first thread to process first */


 /*
  pthread_join(tid1,NULL);
  pthread_join(tid2,NULL);
  pthread_join(tid3,NULL);*/

  sleep(1);
  TRUE = 0;/* Stop all the thread */
  sleep(3);
 exit(0);
}