2015-01-31 5 views
-1

Как я могу сделать значение Семафор более одного. Я пытаюсь написать программу, которая инициирует два потока, и два потока запускаются одновременно после выполнения определенного условия. Программа пытается скопировать два массива (b1 и b2) размером 5 в массив 10 * 10. На каждой итерации значения b1 копируются в x [0] [i] в ​​x [4] [i], а значения b2 копируются в x [5] [i] в ​​x [9] [i] (где i - индекс итерации).Сообщение семафора больше одного

результаты в конце должны выглядеть следующим образом:

0 1 2 3 4 5 6 7 8 9 
1 2 3 4 5 6 7 8 9 10 
2 3 4 5 6 7 8 9 10 11 
3 4 5 6 7 8 9 10 11 12 
4 5 6 7 8 9 10 11 12 13 
5 6 7 8 9 10 11 12 13 14 
6 7 8 9 10 11 12 13 14 15 
7 8 9 10 11 12 13 14 15 16 
8 9 10 11 12 13 14 15 16 17 
9 10 11 12 13 14 15 16 17 18 

Я попытался следующий код:

Driver.cpp

#include <sys/types.h> /* Primitive System Data Types */ 
#include <errno.h>  /* Errors      */ 
#include <stdio.h>  /* Input/Output    */ 
#include <stdlib.h>  /* General Utilities   */ 
#include <thread>  /* C++11 Threads    */ 
#include <string.h>  /* String handling    */ 
#include <semaphore.h> /* Semaphore     */ 
#include <vector>  /* Vector      */ 
#include <iostream> 
#include <iomanip> 
#include "handler.h" 
using namespace std; 

sem_t Sema1; 
sem_t Sema2; 
int ThreadsNumber = 2; /* shared variable */ 
int counter; 
vector<std::thread> threadList; 

int main() 
{ 

int x[10][10]; 
int b1[5]; 
int b2[5]; 
sem_init(&Sema1, 0, 2);  /* initialize Sema1 to Lock - binary  semaphore */ 
sem_init(&Sema2, 0, 1);  /* initialize Sema2 to UnLock - binary semaphore */ 

for (int i = 0; i < 10; i++) 
{ 
    sem_wait(&Sema2); 
    counter = ThreadsNumber; 
    // Update the matrix 
    for (int j = 0; j < 5; j++) 
    { 
     b1[j] = j + i; 
     b2[j] = j + i + 5; 
    } 

sem_init(&Sema1, 0, 2); 

     if (i == 0) 
     { 
     // Create the threads during the first interations 
     threadList.push_back(std::thread(handler, x, b1, 0, 0)); 
     threadList.push_back(std::thread(handler, x, b2, 5, 1)); 
     } 


    // Kill all threads in the last iteration 
     if (i == 9) 
    { 
     for (auto& threadID : threadList){ 
      threadID.join(); 
     } 
    } 


} 


for (int i = 0; i < 10; i++) 
{ 
    for (int j = 0; j < 10; j++) 
    { 
     cout << left << setw(4) << x[i][j]; 
    } 
    cout << endl; 
} 

sem_destroy(&Sema1); /* destroy semaphore */ 

/* exit */ 
return 0; 
} /* main() */ 

handler.cpp

#include "handler.h" 
void handler(int x[10][10], int b[], int start, int id) 
{ 
for (int i = 0; i < 10; i++) 
{ 
    sem_wait(&Sema1);  /* down semaphore */ 
    for (int j = start; j < 5 + start; j++) 
    { 
     x[i][j] = b[j - start]; 
    } 

/*  printf("Thread %d: Waiting to print results...\n", id); 

    for (int j = start; j < 5 + start; j++) 
    { 
     printf("x[%d][%d] = %d\n", i, j, x[i][j]); 
    } 
*/ 
    counter--; 
    cout << counter << endl; 
    if (counter == 0) 
    { 
     sem_post(&Sema2); 
    } 
    /* END CRITICAL REGION */ 

} 
} 

handler.h

#include <iostream> 
#include <semaphore.h> 
using namespace std; 

extern sem_t Sema1; 
extern sem_t Sema2; 
extern int ThreadsNumber; 
extern int counter; 


/* prototype for thread routine */ 
void handler(int x[10][10], int b[], int start, int id); 

но это только не сработало, и я не получил ожидаемых результатов. Есть ли другой способ сделать это?

+0

[sem_init()] (http://man7.org/linux/ man-pages/man3/sem_init.3.html) хорошо позволяет инициализировать семафор со значением, отличным от '0'. Неясно, что на самом деле не работало хорошо с вашим использованием. Вам нужно будет вызвать 'sem_wait()' как минимум два раза, чтобы разблокировать семафор из этой исходной ситуации. –

+0

См. Отредактированный вопрос выше – Anas

+0

. Вы действительно не добавляли важную информацию: _Что на самом деле ** не сработало ** с вашим использованием? _ –

ответ

1

После путем из исследования, чтобы семафор я был в состоянии исправить приведенный выше код следующим образом:

driver.cpp

#include <sys/types.h> /* Primitive System Data Types */ 
#include <errno.h>  /* Errors      */ 
#include <stdio.h>  /* Input/Output    */ 
#include <stdlib.h>  /* General Utilities   */ 
#include <thread>  /* C++11 Threads    */ 
#include <string.h>  /* String handling    */ 
#include <semaphore.h> /* Semaphore     */ 
#include <vector>  /* Vector      */ 
#include <iostream> 
#include <iomanip> 
#include "handler.h" 
using namespace std; 
sem_t Sema1; 
sem_t Sema2; 
int ThreadsNumber = 2; /* shared variable */ 
int counter; 
vector<std::thread> threadList; 

int main() 
{ 

int x[10][10]; 
int b1[5]; 
int b2[5]; 
sem_init(&Sema1, 0, 0);  /* initialize Sema1 to Lock - binary semaphore */ 
sem_init(&Sema2, 0, 2);  /* initialize Sema2 to UnLock - binary semaphore */ 
// Create the threads during the first interations 
threadList.push_back(std::thread(handler, x, b1, 0, 0)); 
threadList.push_back(std::thread(handler, x, b2, 5, 1)); 

for (int i = 0; i < 10; i++) 
{ 
    sem_wait(&Sema2); 
    sem_wait(&Sema2); 
    //counter = ThreadsNumber; 
    // Update the matrix 
    for (int j = 0; j < 5; j++) 
    { 
     b1[j] = j + i; 
     b2[j] = j + i + 5; 
    } 

    for (int i = 0; i < ThreadsNumber; i++) 
    { 
     sem_post(&Sema1); 
    } 
} 

// Kill all threads in the last iteration 
for (auto& threadID : threadList){ 
    threadID.join(); 
} 

for (int i = 0; i < 10; i++) 
{ 
    for (int j = 0; j < 10; j++) 
    { 
     cout << left << setw(4) << x[i][j]; 
    } 
    cout << endl; 
} 

sem_destroy(&Sema1); /* destroy semaphore */ 

/* exit */ 
return 0; 
} /* main() */ 

handler.cpp

#include "handler.h" 
void handler(int x[10][10], int b[], int start, int id) 
{ 
for (int i = 0; i < 10; i++) 
{ 
    sem_wait(&Sema1);  /* down semaphore */ 

    for (int j = start; j < 5 + start; j++) 
    { 
     x[i][j] = b[j - start]; 
    } 

     sem_post(&Sema2); 

    /* END CRITICAL REGION */ 

} 
} 

driver.h

#include <iostream> 
#include <semaphore.h> 
using namespace std; 
extern sem_t Sema1; 
extern sem_t Sema2; 
extern int ThreadsNumber; 
/* prototype for thread routine */ 
void handler(int x[10][10], int b[], int start, int id); 
Смежные вопросы