计算机操作系统-生产者消费者问题C&C++实现

今儿个看了看consumer-producer问题感觉应该比较简单,就打算用C&C++实现一下,好吧果然很简单。

 

唯一困扰我比较久的问题就是,C和C++的隐藏机制有一部分不是很一样,导致两者代码不能很好的融合。

问题如下:

  线程创建时由于C会隐式的把通用指针转换成其他类型指针,但是在C11标准中C++并不会这么做,SO我在这上面浪费了好久的时间FUCK!!!体现出来就是C++的线程函数必须是(void [*])(*) (void *)形式。

下面就直接上代码啦

C代码:

/*
*  > @CopyRight
*  > PROJECTNAME : PthreadTest
*  > FILENAME    : Thread.c
*  > AUTHOR      : Catalpeak
*  > TIME        : 2018.9.29
*  > CONNECTION  : 784734297@163.com
*  > LIAONING UNIVERSITY LNU
*/

#include "Thread.h"

void
Consumer (void * _msg);

void
Producer (void * _msg);

int main ()
{
    char *msg1 = "Consumer pthread has been created";
    char *msg2 = "Producer pthread has been created";
    char *msg3 = "Consumer pthread created fail";
    char *msg4 = "Producer pthread created fail";
    char *msg5 = "Consumer pthread join fail";
    char *msg6 = "Producer pthread join fail";
    pthread_t ConsumerPthread, ProducerPthread;
    void * retval; // Return Value
    int ConsumerPthreadCreateSuccess = 0, ProducerPthreadCreateSuccess = 0;
    int ConsumerPthreadJoinSuccess = 0, ProducerPthreadJoinSuccess = 0;

    InitThread ();

    ConsumerPthreadCreateSuccess =
        pthread_create (&ConsumerPthread, NULL, (void *) &Consumer, (void *) msg1);
    if (ConsumerPthreadCreateSuccess != 0) {
        printf ("%s\n", msg3);
        return 0x00000002;
    }

    ProducerPthreadCreateSuccess =
        pthread_create (&ProducerPthread, NULL, (void *) &Producer, (void *) msg2);
    if (ProducerPthreadCreateSuccess != 0) {
        printf ("%s\n", msg4);
        return 0x00000003;
    }

    // Start Pthread
    ConsumerPthreadJoinSuccess =
        pthread_join (ConsumerPthread, &retval);
    if (ConsumerPthreadJoinSuccess != 0) {
        printf ("%s\n", msg5);
        return 0x00000004;
    }

    ProducerPthreadJoinSuccess =
        pthread_join (ProducerPthread, &retval);
    if (ProducerPthreadJoinSuccess != 0) {
        printf ("%s\n", msg6);
        return 0x00000005;
    }

    return 1;
}

void
Consumer (void * _msg) {
    int nowNumber = 0;
    printf ("%s\n", (char *)_msg);
    do {
        wait (BUFFER_FULL);
        wait (PTHREAD_MUTEX);
        nowNumber = DeQueue (&buffer);
        signature (PTHREAD_MUTEX);
        signature (BUFFER_EMPTY);
        Caculate (nowNumber);
    } while (1);
}

void
Producer (void * _msg) {
    int AddNumber = 0;
    printf ("%s\n", (char *)_msg);
    do {
        AddNumber = rand () % 10 + 1;
        wait (BUFFER_EMPTY);
        wait (PTHREAD_MUTEX);
        EnQueue (&buffer, AddNumber);
        signature (PTHREAD_MUTEX);
        signature (BUFFER_FULL);
    } while (1);
}
/*
* > Thread.h
*/

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include "../MySignal/mSignal.h"
#include <semaphore.h>
#include <time.h>

#define semaphore pthread_mutex_t

#define BUFFER_EMPTY 1
#define BUFFER_FULL  2
#define PTHREAD_MUTEX 3

Signal buffer;
// @brief mutex LOCK variable
semaphore mutex = PTHREAD_MUTEX_INITIALIZER;
// @brief empty message variable
sem_t empty;
// @brief full message variable
sem_t full;

double SUMNUMBER = 0.0;

void
wait (int type);

void
signature (int type);

void
Caculate (int number);

void InitThread ();

void InitThread () {
    sem_init (&empty, 0, 999);
    sem_init (&full, 0, 1);
    srand ((unsigned int) time (NULL));
    InitSignalQueue (&buffer);
}

void
wait (int type) {
    switch (type) {
        case BUFFER_EMPTY: {
            sem_wait (&empty);
        } break;
        case BUFFER_FULL: {
            sem_wait (&full);
        } break;
        case PTHREAD_MUTEX: {
            if (0 != pthread_mutex_lock (&mutex)) {
                printf ("ERROR 0x00000008 in Wait \"PTHREAD_MUTEX_LOCK\"\n");
                perror ("ERROR 0x00000008 in Wait \"PTHREAD_MUTEX_LOCK\"\n");
                exit (EXIT_FAILURE);
            }
        } break;
        default : {
            printf ("ERROR 0x00000006 Wait inputs wrong value\n");
        } break;
    };
    return;
}

void
signature (int type) {
    switch (type) {
        case BUFFER_EMPTY: {
            sem_post (&empty);
        } break;
        case BUFFER_FULL: {
            sem_post (&full);
        } break;
        case PTHREAD_MUTEX: {
            if (0 != pthread_mutex_unlock (&mutex)) {
                printf ("ERROR 0x00000009 in signature \"PTHREAD_MUTEX_UNLOCK\"\n");
                perror ("ERROR 0x00000009 in signature \"PTHREAD_MUTEX_UNLOCK\"\n");
                exit (EXIT_FAILURE);
            }
        } break;
        default : {
            printf ("ERROR 0x00000007 Signature inputs wrong value\n");
        } break;
    };
    return;
}

void
Caculate (int number) {
    SUMNUMBER += number;
    if (SUMNUMBER >= 10000000000.0) {
        SUMNUMBER = 0.0;
    }
    printf ("%.lf\n", SUMNUMBER);
}
/*
* > mSignal.h
*/

/* @CopyRight 2018-9-21 21:52 LiaoNing University
 * Author     : Catalpeak
 * Data       : 2018-9-21
 * connection : 784734297@163.com
 */

#ifndef MSIGNAL_H
#define MSIGNAL_H

#include <stdio.h>

// Change Type of Element here
#define ElemType char

#define SIGNALLENGTH 1000 // The length of all signals in one period

typedef struct Signal {
  ElemType signal [SIGNALLENGTH]; // Save Element
  int SignalSize; // The MAX Size of Signal Queue
  int head; // The number point to head of Queue
  int tail; // The number point to tail of Queue
} Signal ;

/* Function : Initialize Signal Queue
 * Para     : struct Signal pointer
 * Return   : void
 */
void InitSignalQueue (Signal* _signal);

/* Function : Insert a value in signal's tail
 * Para     : ElemType macro definition
 * Para     : struct Signal pointer
 * Return   : void
 */
void EnQueue (Signal* _signal, ElemType value);

/* Function : Get the first element of signal vector
 * Para     : struct Signal signal pointer
 * Return   : ElemType
 */
ElemType DeQueue (Signal* _signal);

/* Function : judge if this Queue is empty
 * Para     : struct signal pointer
 * Return   : int , 1 - yes \ 2 - no
 */
int IfEmpty (Signal* _signal);

/* Function : judge if this Queue is filled
 * Para     : struct signal pointer
 * Return   : int , 1 - yes / 2 - no
 */
 int IfFull (Signal* _signal);

#endif // MSIGNAL_H
/*
* > mSignal.c
*/

/* @CopyRight 2018-9-21 21:52 LiaoNing University
 * Author     : Catalpeak
 * Data       : 2018-9-21
 * connection : 784734297@163.com
 */

#include "mSignal.h"

void InitSignalQueue (Signal* _signal) {
  _signal->head = 0;
  _signal->tail = 0;
  _signal->SignalSize = SIGNALLENGTH;
}

void EnQueue(Signal* _signal, ElemType value) {
  if ((_signal->tail + 1) % _signal->SignalSize == _signal->head) {
    // Signal Queue has filled can't insert
  } else {
    _signal->signal [_signal->tail] = value;
    _signal->tail = (_signal->tail + 1) % _signal->SignalSize;
  }
}

ElemType DeQueue (Signal* _signal) {
  int temp;
  if (_signal->head == _signal->tail) {
    // This Queue is empty can't get element
  } else {
    temp = _signal->signal [_signal->head];
    _signal->head = (_signal->head + 1) % _signal->SignalSize;
  }
  return temp;
}

int IfEmpty (Signal* _signal) {
  if  (_signal->head == _signal->tail) {
    return 1;
  } else {
    return 0;
  }
}

int IfFull (Signal* _signal) {
  if ((_signal->tail + 1) % _signal->SignalSize == _signal->head) {
    return 1;
  } else {
    return 0;
  }
}

C++代码如下:

/*
* > main.cpp
*/

#include "../Header/main.h"

int main ()
{
    pthread_t consumerPthread, producerPthread;
    char *_msg1 = "FUCK1";// = "Consumer thread has been created";
    char *_msg2 = "FUCK2";// = "Producer thread has been created";
    int returnProducer, returnConsumer;
    void *retConsumer, *retProducer;
    returnConsumer = pthread_create (&consumerPthread, NULL, Consumer, (void *) _msg1);
    returnProducer = pthread_create (&producerPthread, NULL, Producer, (void *) _msg2);
    returnConsumer = pthread_join (consumerPthread, &retConsumer);
    returnProducer = pthread_join (producerPthread, &retProducer);
    return 1;
}

void* Producer (void * msg) {
    printf ("%s\n", (char *)msg);
    do {
    //Sleep (100);
    while (produceMutex < 0);
    produceMutex--;
    while (mutex <= 0);
    mutex--;
    /*
    cout << "In Producer thread" << endl;
    cout << "produceMutex is : " << produceMutex << endl;
    cout << "consumeMutex is : " << consumeMutex << endl;
    cout << "mutex should be 0 " << "And now is ; " << mutex << endl;
    */
    int temp = rand () % 10;
    buffer [consumeMutex] = to_String (temp, 1);
    //cout << buffer [consumeMutex] << endl;
    mutex++;
    consumeMutex++;
    } while (1);
    return (void*) 1;
}

void* Consumer (void * msg) {
    printf ("%s\n", (char*)msg);
    do {
    //Sleep (100);
    while (consumeMutex <= 0);
    consumeMutex--;
    while (mutex <= 0);
    mutex--;
    /*
    cout << "In Consumer thread" << endl;
    cout << "produceMutex is : " << produceMutex << endl;
    cout << "consumeMutex is : " << consumeMutex << endl;
    cout << "mutex should be 0 " << "And now is ; " << mutex << endl;
    */
    cout << buffer [consumeMutex] << endl;
    mutex++;
    produceMutex++;
    } while (1);
    return (void*) 1;
}
/*
* > main.h
*/

#include <iostream>
#include <string>
#include <pthread.h>
#include <time.h>
#include <windows.h>
#include <cstdio>
#include "../../utils/utils.h"

using namespace std;

// The size of buffer
#define SIZE_ 10

// Mutually variable
int mutex = 1;

// consumer Mutex
int consumeMutex = 0;

// Produce Mytex
int produceMutex = SIZE_;

// Buffer for save
string buffer [SIZE_];

void*
Producer (void * msg);

void*
Consumer (void * msg);
/*
* > utils.h
*/

#include <string>

#define API_ ;

API_ std::string to_String(int n, int max);
/*
* > utils.cpp
*/

#include "utils.h"

std::string to_String(int n, int max)
{
    int m = n;
    char s[max];
    char ss[max];
    int i=0,j=0;
    if (n < 0)// ´¦Àí¸ºÊý
    {
        m = 0 - m;
        j = 1;
        ss[0] = '-';
    }
    while (m>0)
    {
        s[i++] = m % 10 + '0';
        m /= 10;
    }
    s[i] = '\0';
    i = i - 1;
    while (i >= 0)
    {
        ss[j++] = s[i--];
    }
    ss[j] = '\0';
    return ss;
}

我的编辑器不支持.cc的后缀,写cpp感觉好不舒服啊啊啊啊。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值