Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <semaphore.h>
- #include <pthread.h>
- sem_t canConsume;
- sem_t canProduce;
- sem_t mutex;
- bool consumeFinish = false;
- bool produceFinish = false;
- size_t bufferSize = 0;
- unsigned int *buffer = nullptr;
- void printBuffer() {
- std::cout << "Buffer: ";
- for (size_t i = 0; i < bufferSize; i++) {
- std::cout << buffer[i] << " ";
- }
- std::cout << std::endl;
- }
- unsigned int get_buffer() {
- for (size_t i = 0; i < bufferSize; i++) {
- if (buffer[i] == 1) {
- buffer[i] = 0;
- return (unsigned int) i;
- }
- }
- }
- unsigned int push_buffer() {
- for (size_t i = 0; i < bufferSize; i++) {
- if (buffer[i] == 0) {
- buffer[i] = 1;
- return (unsigned int) i;
- }
- }
- }
- void *produce(void *threadId) {
- unsigned int id = *((unsigned int *) threadId);
- unsigned int pos = 0;
- do {
- sem_wait(&canProduce);
- sem_wait(&mutex);
- // produce action
- pos = push_buffer();
- sem_post(&mutex);
- sem_post(&canConsume);
- } while (!produceFinish);
- pthread_exit(0);
- }
- void *consume(void *threadId) {
- unsigned int id = *((unsigned int *) threadId);
- unsigned int pos = 0;
- do {
- sem_wait(&canConsume);
- sem_wait(&mutex);
- // consume action
- pos = get_buffer();
- sem_post(&mutex);
- sem_post(&canProduce);
- } while (!consumeFinish);
- pthread_exit(0);
- }
- bool validateArgs(int argc, char *argv[], int &numThreadsProducers, int &numThreadsConsumers) {
- // receive arguments - validate and save
- if (argc != 6) {
- std::cerr << "Number of arguments invalid!" << std::endl;
- return false;
- }
- if (atoi(argv[1])) {
- bufferSize = std::stoi(argv[1]);
- } else {
- std::cerr << argv[1] << ": is not valid number!" << std::endl;
- return false;
- }
- if (atoi(argv[2])) {
- numThreadsProducers = std::stoi(argv[2]);
- } else {
- std::cerr << argv[2] << ": is not valid number!" << std::endl;
- return false;
- }
- if (strcmp(argv[3], "1") == 0 || strcmp(argv[3], "true") == 0) {
- produceFinish = true;
- } else if (strcmp(argv[3], "0") == 0 || strcmp(argv[3], "false") != 0) {
- std::cerr << argv[3] << ": is not valid boolean!" << std::endl;
- return false;
- }
- if (atoi(argv[4])) {
- numThreadsConsumers = std::stoi(argv[4]);
- } else {
- std::cerr << argv[4] << ": is not valid number!" << std::endl;
- return false;
- }
- if (strcmp(argv[5], "1") == 0 || strcmp(argv[5], "true") == 0) {
- consumeFinish = true;
- } else if (strcmp(argv[5], "0") == 0 || strcmp(argv[5], "false") != 0) {
- std::cerr << argv[5] << ": is not valid boolean!" << std::endl;
- return false;
- }
- return true;
- }
- int main(int argc, char *argv[]) {
- int numThreadsProducers = 0, numThreadsConsumers = 0;
- // validate and save
- if (!validateArgs(argc, argv, numThreadsProducers, numThreadsConsumers)) {
- return -1;
- }
- // initialize buffer
- buffer = new unsigned int[bufferSize];
- for (int i = 0; i < bufferSize; i++) {
- buffer[i] = 0;
- }
- // initialize semaphores
- sem_init(&canProduce, 0, bufferSize);
- sem_init(&canConsume, 0, 0);
- sem_init(&mutex, 0, 1);
- // create threads arrays
- pthread_t *consumersThreadsArray = new pthread_t[numThreadsConsumers];
- pthread_t *producersThreadsArray = new pthread_t[numThreadsProducers];
- // create producers threads
- for (int threadId = 0; threadId < numThreadsProducers; threadId++) {
- pthread_create(&(producersThreadsArray[threadId]), NULL, produce, &threadId);
- }
- // create consumers threads
- for (int threadId = 0; threadId < numThreadsConsumers; threadId++) {
- pthread_create(&(consumersThreadsArray[threadId]), NULL, consume, &threadId);
- }
- // threads join
- for (int i = 0; i < numThreadsProducers; i++) {
- pthread_join(producersThreadsArray[i], nullptr);
- }
- for (int i = 0; i < numThreadsConsumers; i++) {
- pthread_join(consumersThreadsArray[i], nullptr);
- }
- // print buffer
- printBuffer();
- // delete memory
- sem_destroy(&canProduce);
- sem_destroy(&canConsume);
- sem_destroy(&mutex);
- delete [] buffer;
- delete [] consumersThreadsArray;
- delete [] producersThreadsArray;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement