NVIDIA Interview Question
Software Engineer InternsTeam: Driver Development
Country: United States
Interview Type: Phone Interview
The mutex and cond vars should be destroyed at the end of main func. And I edited my submit to reflect that change. Apologize for my carelessness.
- (void)runNumbersTest {
NumbersWorker *worker = [NumbersWorker new];
worker.limit = 10000;
NSThread *evenThread = [[NSThread alloc] initWithTarget:worker selector:@selector(printEvenNumbers) object:nil];
evenThread.name = @"Even Thread";
NSThread *oddThread = [[NSThread alloc] initWithTarget:worker selector:@selector(printOddNumbers) object:nil];
oddThread.name = @"Odd Thread";
[evenThread start];
[oddThread start];
}
@interface NumbersWorker ()
@property (assign) NSUInteger limit;
@property (strong) NSConditionLock *workerLock;
@property (atomic) NSUInteger curr;
@end
@implementation NumbersWorker
static const NSInteger conditionEven = 0;
static const NSInteger conditionOdd = 1;
- (id)init {
self = [super init];
if(self) {
self.workerLock = [[NSConditionLock alloc] initWithCondition:conditionEven];
self.workerLock.name = @"NumbersLock";
}
return self;
}
- (void)printEvenNumbers {
NSString *threadName = [NSThread currentThread].name;
while (self.curr < self.limit) {
[self.workerLock lockWhenCondition:conditionEven];
NSLog(@"%d - %@ ", self.curr, threadName);
self.curr++;
[self.workerLock unlockWithCondition:conditionOdd];
}
}
- (void)printOddNumbers {
NSString *threadName = [NSThread currentThread].name;
while (self.curr < self.limit) {
[self.workerLock lockWhenCondition:conditionOdd];
NSLog(@"%d - %@ ", self.curr, threadName);
self.curr++;
[self.workerLock unlockWithCondition:conditionEven];
}
}
Working on linux:
#include <pthread.h>
#include <stdio.h>
pthread_mutex_t lock;
pthread_cond_t cv;
int turn = 0;
void *print_num(void *arg)
{
int my_turn = arg ? 1 : 0;
for (int i = my_turn; i < 100; i += 2) {
pthread_mutex_lock(&lock);
while (my_turn != turn)
pthread_cond_wait (&cv, &lock);
turn = (turn + 1) % 2;
printf ("%d ", i);
pthread_cond_signal (&cv);
pthread_mutex_unlock(&lock);
}
printf ("\n");
pthread_exit(0);
}
int main (int argc, char *argv[])
{
pthread_mutex_init(&lock, NULL);
pthread_cond_init (&cv, NULL);
pthread_t odd, even;
pthread_create(&even, NULL, print_num, (void *)0);
pthread_create(&odd, NULL, print_num, (void *)1);
pthread_join(even, NULL);
pthread_join(odd, NULL);
pthread_mutex_destroy(&lock);
pthread_cond_destroy(&cv);
return 0;
}
#include <iostream>
#include <thread>
#include <chrono>
#include <mutex>
#include <condition_variable>
using namespace std;
mutex mtx;
condition_variable cv;
int nGoEven = 1;
int nGoOdd = 0;
void print_even(const int nMax) {
for (int i = 0; i < nMax; ++i) {
unique_lock<mutex> lck(mtx);
while (nGoEven == 0) cv.wait(lck);
cout << " " << i * 2 << endl;
nGoEven = 0;
nGoOdd = 1;
this_thread::sleep_for(chrono::microseconds(1));
cv.notify_one();
}
}
void print_odd(const int nMax) {
for (int i = 0; i < nMax; ++i) {
unique_lock<mutex> lck(mtx);
while (nGoOdd == 0) cv.wait(lck);
cout << " " << i * 2 + 1 << endl;
nGoEven = 1;
nGoOdd = 0;
this_thread::sleep_for(chrono::microseconds(1));
cv.notify_one();
}
}
int main(int argc, char *argv[])
{
int nMax = 20;
thread runner1(print_even, nMax);
thread runner2(print_odd, nMax);
runner1.join();
runner2.join();
getchar();
return 0;
}
#include <stdio.h>
#include <pthread.h>
void printOdd(void *max){
int limit;
int i = 1;
limit = (int)max;
while(i <= limit){
printf("%d\n",i);
i = i+2;
sched_yield();
}
}
void printEven(void * max){
int limit;
int i = 0;
limit = (int)max;
while(i <= limit){
printf("%d\n",i);
i = i+2;
sched_yield();
}
}
int main(){
int limit;
printf("Enter the maximum value till which you would like to print\n");
scanf("%d",&limit);
printf("\nPrinting\n");
pthread_t evenThread, oddThread;
pthread_create(&evenThread, NULL, printEven, (void *)limit);
pthread_create(&oddThread, NULL, printOdd, (void *)limit);
pthread_join(evenThread, NULL);
pthread_join(oddThread, NULL);
return 0;
}
Implementation using mutex and condition var.
- Tony L February 13, 2014