Reputation:
I made a little example program that counts numbers using two threads. It also prints a second number next to the count so I can see which thread printed which number.
Now my goal is to make both threads immediately stop once one of them counted 7. I don't know how to go about it. I thought about passing a thread array as a parameter to Counter
and then use a foreach loop to abort both threads. The problem is that t0
might be executing it and calls t0.Abort()
and thus t1.Abort()
won't be called anymore.
public static int count = 0;
private static object lockObject = new object();
static void Main(string[] args) {
Thread t0 = new Thread(() => Counter(1, 10));
Thread t1 = new Thread(() => Counter(10, 20));
t0.Start();
t1.Start();
t0.Join();
t1.Join();
Console.ReadLine();
}
public static void Counter(int k, int m) {
for(int i = k; i < m; i++) {
lock (lockObject) {
count++;
Console.WriteLine(count + " " + i);
if (i == 7) {
/*
* Code that will kill thread t0 and t1
*/
}
}
}
}
The output should be something like
1 1
2 2
3 10
4 11
5 12
6 13
7 14
Does someone have suggestions how to kill both t0
and t1
?
Upvotes: 0
Views: 111
Reputation: 5764
Have a look at ManualResetEvent. You should create one and inside the for-loop of the Counter-method you should check if the event is set and if so, break the for-loop and return. If you reach 7, simply set the event. The event is thread-safe.
By the way, seems to be a university homework ;) next time, try it yourself.
public static int count = 0;
private static object lockObject = new object();
private ManualResetEvent finish = new ManualResetEvent(false);
static void Main(string[] args) {
Thread t0 = new Thread(() => Counter(1, 10));
Thread t1 = new Thread(() => Counter(10, 20));
t0.Start();
t1.Start();
t0.Join();
t1.Join();
Console.ReadLine();
}
public static void Counter(int k, int m) {
for(int i = k; i < m; i++) {
lock (lockObject) {
if (finish.waitOne(0))
break;
count++;
Console.WriteLine(count + " " + i);
if (i == 7)
finish.set()
}
}
}
Upvotes: 1
Reputation: 21
MSDN Doesn't know what is ManualResetEvent.isset(), but Matthias's answer looks correct. If replace isset()
to WaitOne(0)
, code works fine.
private static int count = 0;
private static ManualResetEvent finish = new ManualResetEvent(false);
private static int stopValue = 7;
private static int syncInterval = 0; //0ms
private static object lockObject = new object();
static void Main(string[] args)
{
Thread t0 = new Thread(() => Counter(1, 10));
Thread t1 = new Thread(() => Counter(10, 20));
t0.Name = "Thread 1";
t1.Name = "Thread 2";
t0.Start();
t1.Start();
t0.Join();
t1.Join();
Console.ReadKey();
}
public static void Counter(int k, int m)
{
for (int i = k; i < m; i++)
{
lock (lockObject)
{
if (finish.WaitOne(syncInterval))
break;
count++;
Console.WriteLine($"{count} {i}");
if (count == stopValue)
{
finish.Set();
}
}
}
}
Upvotes: 0
Reputation: 1465
Use a flag, in this case "run".
public static int count = 0;
private static object lockObject = new object();
static bool run = true;
static void Main(string[] args) {
Thread t0 = new Thread(() => Counter(1, 10));
Thread t1 = new Thread(() => Counter(10, 20));
t0.Start();
t1.Start();
t0.Join();
t1.Join();
Console.ReadLine();
}
public static void Counter(int k, int m) {
for(int i = k; i < m && run; i++) {
lock (lockObject) {
count++;
Console.WriteLine(count + " " + i);
if (i == 7) {
run = false;
}
}
}
}
Upvotes: 2