Using Peterson's solution for mutual exclusion

The idea was to have the producer thread run BEFORE the consumer thread. Always. But my program runs the consumer thread before the producer sometimes. I have used Peterson's solution to achieve mutual exclusion, but that does not guarantee the above criterion of the Producer being run first. What are my options? I know many of you are going to recommend semaphores. If so, would you be kind enough to modify my code so that it implements semaphores.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
#include <windows.h>
#include <stdio.h> 
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <fstream>
#include <ctime>
using namespace std;

//This is class for the circular buffer
template <class T>
class CircularBuffer
{
private:
	size_t _size;
	unsigned current;
	unsigned currentMark;
	T *entry;
	int items;
	int temp;

public:
	CircularBuffer(size_t size, T v): _size(size)
	{
		entry = new T[_size];
		reset(v);
	}
	~CircularBuffer()
	{
    delete [] entry;
	}

	inline void reset(T v)
	{
    fill(entry, entry + _size, v);
    current = 0;
    currentMark = 0;
	items = 0;
	temp = -1;
	}

	inline T & get(int position) const
	{
    int myIndex = current - position;
    if ( myIndex < 0 )
		myIndex += _size;
    return entry[myIndex] ;
	}
	inline T & getWhole()
	{
		//cout << current << " is current" << endl;
		int index = current - temp;
		if (index < 0){
			index += _size;}
		temp--;
		return entry[index];
	}

	inline void putArray(double *arr, int len) 
	{
    if (current + len >= size) {
    	int first_slice = size - current - 1; 
    	memcpy((char *)(entry + current + 1), (char *)arr, sizeof(double)*(first_slice));	
    	memcpy((char *)(entry), (char *)(arr + first_slice), sizeof(double)*(len - first_slice));    	
    }
    else {
    	memcpy((char *)(entry + current + 1), (char *)arr, sizeof(double)*len);
    }
    current = (current + len) % size;
	}

	inline T & getFromMark(int position) const
	{
	int myIndex = currentMark - position;
	if (myIndex < 0 ) myIndex += size;
	return entry [myIndex];	
	}

	inline void moveMark(int steps) 
	{
	currentMark += steps;
	if (currentMark > size-1)
		currentMark -= size;
	}
    //Implements the circularity
	inline void put(const T &elem)
	{
    if (current < _size-1)
        current++;
    else
        current=0;

    entry[current] = elem;
	items++;
	temp++;
	}
	int SlotsAvailable(){
		return (29 - items);
	}
	int numitems(){
		return items;
	}
};

int ARRAY_SIZE = 30;
int interested[2] = {0, 0};
int turn;
ifstream inputFile;
ofstream outputFile;
CircularBuffer<int> Buffer(ARRAY_SIZE, 0);

//PRODUCER THREAD
DWORD WINAPI Producer(LPVOID Param)
{ 
	int count = 0;
	int integer = *(int*)Param;
	int other;
	interested[0] = 1;
	int numb[1];
	int c = 0;
	
	turn = 1;
	while(interested[1] == 1 && turn == 1)
		;//donothing
	while (count < integer && inputFile >> numb[0]){ 
		c = numb[0];
		Buffer.put(c);
		count++;
	}
	cout << endl;
	cout << "There are " << Buffer.numitems() << " element(s) in the Buffer" << endl;
	cout << endl;

	interested[0] = 0;
	return 0;
}
//CONSUMER THREAD
DWORD WINAPI Consumer(LPVOID Param)
{ 
	int integer2 = *(int*)Param;
	int other;
	int count = 0;
	
	interested[1] = 1;
	turn = 0;
	while(Buffer.numitems() == 0)
		;//donothing

	while(interested[0] == 1 && turn == 0)
		;//donothing
	int count_variable = Buffer.numitems() - 1;
	cout << "The Current Contents Of The Output File: " << endl;
	for(int index = count_variable; index >= 0; index--){
		cout << Buffer.get(index) << " ";
	}
	cout << endl;
	cout << endl;

	outputFile.open("Output.txt");
	for(count = count_variable; count >= 0; count--){
		outputFile << Buffer.get(count) << endl;
	}
	outputFile.close();

	interested[1] = 0;

	return 0;
}
//MAIN METHOD
int main()
{
	DWORD ThreadId;
	HANDLE ThreadHandle, ThreadConsumer;
	unsigned seed = time(0);
	//Seed The Random Number Generator
	srand(seed);
	int bound;
	int random_number;
	inputFile.open("numbers.txt");
	
	while(!inputFile.eof())
	{
		cout << "Specify An Upper Bound For The Number Of Bytes To Be Copied: " << endl;
		cin >> bound;
		//Come up with a random number between 1 and bound
		random_number = 1 + rand() % bound;
		cout << endl;
		cout << "N = " << random_number << endl;
		cout << endl;

		if(Buffer.SlotsAvailable() < random_number){
		cout << "Not Enough Empty Slots: Overwrite May Occur" << endl;
		cout << endl;
		continue;
		}

		//Create The Threads
		ThreadHandle = CreateThread(NULL, 0, Producer, &random_number, 0, &ThreadId);
		ThreadConsumer = CreateThread(NULL, 0, Consumer, &random_number, 0, &ThreadId);


		WaitForSingleObject(ThreadHandle,INFINITE);
		WaitForSingleObject(ThreadConsumer, INFINITE);
	}//endwhile
	cout << endl;
	cout << "The Input file has been copied entirely" << endl;
	cout << endl;
	inputFile.close();
}


Topic archived. No new replies allowed.