NVIDIA Interview Question
Software Engineer InternsCountry: United States
Use condition variables to sleep/wake threads based on condition
#include "stdafx.h"
#include <iostream>
#include <thread>
#include <Windows.h>
#include <WinBase.h>
using namespace std;
static int i=0;
CRITICAL_SECTION CritSection;
CONDITION_VARIABLE ConditionVarodd;
CONDITION_VARIABLE ConditionVareven;
void printodd()
{
while (i<150)
{
EnterCriticalSection(&CritSection);
if(i%2 == 0)
{
SleepConditionVariableCS(&ConditionVarodd, &CritSection, INFINITE);
}
printf("\n odd %d",i);
i++;
LeaveCriticalSection(&CritSection);
WakeConditionVariable(&ConditionVareven);
}
}
void printeven()
{
while(i<150)
{
EnterCriticalSection(&CritSection);
if(i%2 == 1)
{
SleepConditionVariableCS(&ConditionVareven, &CritSection, INFINITE);
}
printf("\n even %d",i);
i++;
LeaveCriticalSection(&CritSection);
WakeConditionVariable(&ConditionVarodd);
}
}
int main()
{
InitializeCriticalSection(&CritSection);
InitializeConditionVariable(&ConditionVarodd);
InitializeConditionVariable(&ConditionVareven);
thread t1(printodd);
thread t2(printeven);
t1.join();
t2.join();
DeleteCriticalSection(&CritSection);
WakeAllConditionVariable(&ConditionVarodd);
WakeAllConditionVariable(&ConditionVareven);
return 0;
}
Easier approach would be to use a global flag which is initially set to 0. Odd thread will work only when the global flag is 1 while even thread will work only when global flag is 0. Odd thread will set the value to 0 after one print while the even thread will set value to 1 after one print. If you see we are indirectly using the binary semaphore in the form of global flag which is not expensive at all. We don’t need any semaphore while modifying the global flag’s value.
HANDLE p,v;
void odd()
{
int a =0;
while(a<100)
{
WaitForSingleObject(p,-1);
printf("%d ",a);
a=a+2;
ReleaseSemaphore( v,1,NULL);
}
}
void even()
{
int a =1;
while(a<100)
{
WaitForSingleObject(v,-1);
printf("%d ",a);
a=a+2;
ReleaseSemaphore( p,1,NULL);
}
}
void twothread()
{
int i=0;
p = CreateSemaphore(
NULL, // default security attributes
1, // initial count
1, // maximum count
NULL); // unnamed semaphore
v = CreateSemaphore(
NULL, // default security attributes
0, // initial count
1, // maximum count
NULL); // unnamed semaphore
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)&odd,(LPVOID) &i,0,NULL);
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)&even,(LPVOID) &i,0,NULL);
while(1);
}
pthread_cond _t cv;
pthread_mutex_t mt;
bool flag=0;
int main() {
pthread_t even,odd;
pthread_create(&even,&attr,printeven,NULL);
pthread_create(&odd,&attr,printodd,NULL);
pthread_join(even,NULL);
pthread_join(odd,NULL);
}
void printeven( ) {
for (int i=0; i+=2) {
pthread_mutex_lock(&mt);
if (flag)
pthread_cond_wait(&cv,&mt);
flag = 1;
printf("%d",i);
pthread_cond_signal(&cv,&mt);
pthread_mutex_unlock(&mt);
}
void printodd( ) {
for (int i=1; i+=2) {
pthread_mutex_lock(&mt);
if (!flag)
pthread_cond_wait(&cv,&mt);
flag = 0;
printf("%d",i);
pthread_cond_signal(&cv,&mt);
pthread_mutex_unlock(&mt);
}
extern "C"
{
#include "pthread.h"
}
#include <iostream>
#define NUM_THREADS 2
#define kMAX 20
using namespace std;
int k = 0; //global variable == private field in a class implementing these fcns
//mutex is used to protect critical section, has nothing to do with wait&signal
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
//condition variables are used by threads to obtain and deliver turn (wait&signal)
pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
void* print_odd(void* threadId){
while(k<kMAX){
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cv,&mutex);
if(k&1){ //if k is odd
cout << k << " ";
k++;
}
//pthread_cond_signal(&cv);
pthread_mutex_unlock(&mutex);
}
pthread_exit(NULL);
return NULL;
}
void* print_even(void* threadId){
while(k< kMAX){
pthread_mutex_lock(&mutex);
//pthread_cond_wait(&cv,&mutex);
if (!(k&1)){ //if k is odd
cout << k << " ";
k++;
}
pthread_cond_signal(&cv);
pthread_mutex_unlock(&mutex);
}
pthread_exit(NULL);
return NULL;
}
int main(){
pthread_t threads[NUM_THREADS];
pthread_create(&threads[0],NULL ,print_odd, (void*) 0);
pthread_create(&threads[1],NULL, print_even, (void*) 1);
pthread_join(threads[0] , NULL);
pthread_join(threads[1] , NULL);
}
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <stdbool.h>
bool printOddNum;
int amountOfNums = 30;
pthread_mutex_t theMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cv;
void* printEven(void* vargp)
{
for (int i = 1; i < amountOfNums / 2; i++)
{
pthread_mutex_lock(&theMutex);
while (printOddNum)
{
pthread_cond_wait(&cv, &theMutex);
}
printf("%d\n", 2 * i);
printOddNum = true;
pthread_cond_signal(&cv);
pthread_mutex_unlock(&theMutex);
}
return NULL;
}
void* printOdd(void* vargp)
{
for(int i = 1; i < amountOfNums / 2; i++)
{
pthread_mutex_lock(&theMutex);
while (!printOddNum)
{
pthread_cond_wait(&cv, &theMutex);
}
printf("%d\n", 2 * i - 1);
printOddNum = false;
pthread_cond_signal(&cv);
pthread_mutex_unlock(&theMutex);
}
return NULL;
}
int main()
{
pthread_t evenThreadID;
pthread_t oddThreadID;
printOddNum = true;
pthread_mutex_init(&theMutex, NULL);
pthread_cond_init(&cv, NULL);
pthread_create(&oddThreadID, NULL, printOdd, NULL);
pthread_create(&evenThreadID, NULL, printEven, NULL);
pthread_join(evenThreadID, NULL);
pthread_join(oddThreadID, NULL);
pthread_mutex_destroy(&theMutex);
pthread_cond_destroy(&cv);
system("pause");
return 0;
}
#include <stdio.h>
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex evenMutex, oddMutex;
int nextEven = 0, nextOdd = 1;
int nMax = 100;
void printOdd()
{
while(nextOdd <= nMax && nextEven <= nMax)
{
oddMutex.lock();
std::cout << nextOdd << std::endl;
nextOdd +=2;
evenMutex.unlock();
}
}
void printEven()
{
while(nextOdd <= nMax && nextEven <= nMax)
{
evenMutex.lock();
std::cout << nextEven << std::endl;
nextEven +=2;
oddMutex.unlock();
}
}
int main()
{
evenMutex.unlock();
oddMutex.lock();
std::thread t1(printOdd);
std::thread t2(printEven);
t1.join();
t2.join();
std::cout << "Press Enter to continue ..." << std::endl;
std::cin.get();
return 0;
}
#include <stdio.h>
#include <iostream>
#include <thread>
#include <mutex>
std::mutex evenMutex, oddMutex;
int nextEven = 0, nextOdd = 1;
int nMax = 100;
void printOdd()
{
while(nextOdd <= nMax && nextEven <= nMax)
{
oddMutex.lock();
std::cout << nextOdd << std::endl;
nextOdd +=2;
evenMutex.unlock();
}
}
void printEven()
{
while(nextOdd <= nMax && nextEven <= nMax)
{
evenMutex.lock();
std::cout << nextEven << std::endl;
nextEven +=2;
oddMutex.unlock();
}
}
int main()
{
evenMutex.unlock();
oddMutex.lock();
std::thread t1(printOdd);
std::thread t2(printEven);
t1.join();
t2.join();
std::cout << "Press Enter to continue ..." << std::endl;
std::cin.get();
return 0;
}
#include <stdio.h>
#include <iostream>
#include <thread>
#include <mutex>
std::mutex evenMutex, oddMutex;
int nextEven = 0, nextOdd = 1;
int nMax = 100;
void printOdd()
{
while(nextOdd <= nMax && nextEven <= nMax)
{
oddMutex.lock();
std::cout << nextOdd << std::endl;
nextOdd +=2;
evenMutex.unlock();
}
}
void printEven()
{
while(nextOdd <= nMax && nextEven <= nMax)
{
evenMutex.lock();
std::cout << nextEven << std::endl;
nextEven +=2;
oddMutex.unlock();
}
}
int main()
{
evenMutex.unlock();
oddMutex.lock();
std::thread t1(printOdd);
std::thread t2(printEven);
t1.join();
t2.join();
std::cout << "Press Enter to continue ..." << std::endl;
std::cin.get();
return 0;
}
#include <stdio.h>
#include <iostream>
#include <thread>
#include <mutex>
std::mutex evenMutex, oddMutex;
int nextEven = 0, nextOdd = 1;
int nMax = 100;
void printOdd()
{
while(nextOdd <= nMax && nextEven <= nMax)
{
oddMutex.lock();
std::cout << nextOdd << std::endl;
nextOdd +=2;
evenMutex.unlock();
}
}
void printEven()
{
while(nextOdd <= nMax && nextEven <= nMax)
{
evenMutex.lock();
std::cout << nextEven << std::endl;
nextEven +=2;
oddMutex.unlock();
}
}
int main()
{
evenMutex.unlock();
oddMutex.lock();
std::thread t1(printOdd);
std::thread t2(printEven);
t1.join();
t2.join();
std::cout << "Press Enter to continue ..." << std::endl;
std::cin.get();
return 0;
}
Here's a simple java program
public class OddEvenVolatile {
public volatile boolean printOdd = false;
public volatile boolean printEven = false;
public static void main (String [] args) {
OddEvenVolatile oev = new OddEvenVolatile();
PrintEven e = oev.new PrintEven();
PrintOdd o = oev.new PrintOdd();
Thread to = new Thread(o);
Thread te = new Thread(e);
te.start();
to.start();
oev.printEven = true;
}
private class PrintEven implements Runnable {
public void run() {
for(int i = 0; i <= 10; i += 2) {
while(!printEven) try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i);
synchronized(this) {
printEven = false;
printOdd = true;
}
}
}
}
private class PrintOdd implements Runnable {
public void run() {
for(int i = 1; i <= 10; i += 2) {
while(!printOdd) try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i);
synchronized(this) {
printOdd = false;
printEven = true;
}
}
}
}
}
// Windows solution:
#define _AFXDLL
#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <afxmt.h> // MFC multithreading
CEvent eWaitForTread1Ends;
CEvent eWaitForTread2Ends;
CEvent eWaitForTread1;
CEvent eWaitForTread2;
HANDLE hThread1;
HANDLE hThread2;
//................................................................................................................
DWORD WINAPI TreadFunction1(LPVOID lpParam)
{
int i;
for (i = 1; i <= 10; i = i + 2)
{
eWaitForTread2.ResetEvent(); // signal to wait for thread #2
printf("tread 1: i = %d\n", i);
eWaitForTread2.SetEvent(); // thread #2 can continue
eWaitForTread1.ResetEvent(); // lock this thread (#1)
WaitForSingleObject(eWaitForTread1.m_hObject, INFINITE); // wait until thread #2 allows it
}
eWaitForTread2.SetEvent(); // thread #2 can continue
eWaitForTread1Ends.SetEvent(); // allow to finish the program
return 0;
}
//................................................................................................................
DWORD WINAPI TreadFunction2(LPVOID lpParam)
{
int i;
for (i = 2; i <= 10; i = i + 2)
{
eWaitForTread1.ResetEvent(); // signal to wait for thread #1
printf("tread 2: i = %d\n", i);
eWaitForTread2.ResetEvent(); // // lock this thread (#2)
eWaitForTread1.SetEvent(); // thread #1 can continue
WaitForSingleObject(eWaitForTread2.m_hObject, INFINITE); // wait until thread #1 allows it
}
eWaitForTread1.SetEvent(); // thread #1 can continue
eWaitForTread2Ends.SetEvent(); // allow to finish the program
return 0;
}
int main()
{
eWaitForTread1Ends.ResetEvent();
eWaitForTread2Ends.ResetEvent();
hThread1 = CreateThread(NULL, NULL, TreadFunction1, NULL, NULL, NULL);
hThread1 = CreateThread(NULL, NULL, TreadFunction2, NULL, NULL, NULL);
WaitForSingleObject(eWaitForTread1Ends.m_hObject, INFINITE);
WaitForSingleObject(eWaitForTread2Ends.m_hObject, INFINITE);
getchar();
return 0;
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
int num = 0;
std::mutex mtx;
std::condition_variable cv;
int printNumber(bool even)
{
std::unique_lock<std::mutex> lck(mtx);
for(; num < 100;){
if(even){
while((num&1)) cv.wait(lck);
}
else {
while(!(num&1)) cv.wait(lck);
}
printf("%d\n", num++);
cv.notify_all();
}
return 0;
}
int main()
{
std::thread th[2];
th[0] = std::thread(printNumber, false);
th[1] = std::thread(printNumber, true);
for(int i = 0; i < sizeof(th) / sizeof(th[0]); i++)
th[i].join();
return 0;
}
<code>#include <stdio.h>
#include <omp.h>
int main()
{
#pragma omp parallel
{
int tid = omp_get_thread_num();
int counter = tid;
while(1)
{
if (tid == 0)
printf("%d,",counter);
#pragma omp barrier
if (tid == 1)
printf("%d,",counter);
#pragma omp barrier
counter+=2;
}
}
}
</code>
// condition_variable example
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable
using namespace std;
std::mutex mtx;
std::condition_variable cv;
int current = 0;
void even() {
std::unique_lock<std::mutex> lck(mtx);
while(current <= 100) {
if(current % 2 != 0)
cv.wait(lck);
std::cout << current << '\n';
current++;
cv.notify_one();
}
}
void odd() {
std::unique_lock<std::mutex> lck(mtx);
while(current < 100) {
if(current % 2 == 0)
cv.wait(lck);
std::cout << current << '\n';
current++;
cv.notify_one();
}
}
int main ()
{
std::thread evenThread(even);
std::thread oddThread(odd);
std::cout << "Starting...\n";
evenThread.join();
oddThread.join();
return 0;
}
// condition_variable example
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable
using namespace std;
std::mutex mtx;
std::condition_variable cv;
int current = 0;
void even() {
std::unique_lock<std::mutex> lck(mtx);
while(current <= 100) {
if(current % 2 != 0)
cv.wait(lck);
std::cout << current << '\n';
current++;
cv.notify_one();
}
}
void odd() {
std::unique_lock<std::mutex> lck(mtx);
while(current < 100) {
if(current % 2 == 0)
cv.wait(lck);
std::cout << current << '\n';
current++;
cv.notify_one();
}
}
int main ()
{
std::thread evenThread(even);
std::thread oddThread(odd);
std::cout << "Starting...\n";
evenThread.join();
oddThread.join();
return 0;
}
// condition_variable example
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable
using namespace std;
std::mutex mtx;
std::condition_variable cv;
int current = 0;
void even() {
std::unique_lock<std::mutex> lck(mtx);
while(current <= 100) {
if(current % 2 != 0)
cv.wait(lck);
std::cout << current << '\n';
current++;
cv.notify_one();
}
}
void odd() {
std::unique_lock<std::mutex> lck(mtx);
while(current < 100) {
if(current % 2 == 0)
cv.wait(lck);
std::cout << current << '\n';
current++;
cv.notify_one();
}
}
int main ()
{
std::thread evenThread(even);
std::thread oddThread(odd);
std::cout << "Starting...\n";
evenThread.join();
oddThread.join();
return 0;
}
#define EVEN 0
#define ODD 1
int cs=EVEN;//critical section
int number=0;
sem_t lock=1;
void printEven()
{
while(1)
{
sem_wait(lock);
if( cs == EVEN) {
print("Even Number %d", number);
number++;
cs=ODD;
}
sem_post(lock);
pthread_yield();
}
}
void printOdd()
{
while(1)
{
sem_wait(lock);
if(cs == ODD) {
print("Odd Number %d", number);
number++;
cs = EVEN;
}
sem_post(lock);
pthread_yield();
}
}
//create 1 thread for printOdd() and one for printEven()
import java.util.LinkedList;
public class OddEvenGenerator {
private Object lock = new Object();
private LinkedList<Integer> queue = new LinkedList<>();
private final int LIMIT = 10;
private final int MAX_VALUE = 20;
private void numberProducer() {
int value = 0;
while (true) {
try {
synchronized (lock) {
while (queue.size() == LIMIT) {
lock.wait();
}
if(value < MAX_VALUE ){
queue.add(value);
value = value + 1;
lock.notifyAll();
} else {
lock.notifyAll();
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void printNumber(int num) throws InterruptedException{
System.out.print(num + " ");
Thread.sleep(1000);
}
private void evenConsumer() {
Integer num = 0;
while (num < MAX_VALUE) {
synchronized (lock) {
try {
while (queue.size() == 0) {
lock.wait();
}
num = queue.peek();
if (num % 2 == 0) {
num = queue.removeFirst();
printNumber(num);
}
lock.notify();
} catch (Exception e) {
e.printStackTrace();
break;
}
}
}
}
private void oddConsumer() {
Integer num = 0;
while (num < MAX_VALUE) {
synchronized (lock) {
try {
while (queue.size() == 0) {
lock.wait();
}
num = queue.peek();
if (num % 2 == 1) {
num = queue.removeFirst();
printNumber(num);
}
lock.notify();
} catch (Exception e) {
e.printStackTrace();
break;
}
}
}
}
public static void main(String[] args) throws InterruptedException {
OddEvenGenerator oeg = new OddEvenGenerator();
new Thread(() -> oeg.numberProducer()).start();
new Thread(() -> oeg.evenConsumer()).start();
new Thread(() -> oeg.oddConsumer()).start();
}
}
1 #include <iostream>
2 #include <pthread.h>
3
4 pthread_cond_t cond1;
6 pthread_mutex_t mutex1;
8
9 using namespace std;
10
11 int i = 0;
12
13 void* print0(void *a)
14 {
15 while(1)
16 {
17 pthread_mutex_lock(&mutex1);
18 pthread_cond_signal(&cond1);
19 pthread_cond_wait(&cond1, &mutex1);
20 cout << "thread1 " << i++ << endl;
21 pthread_mutex_unlock(&mutex1);
22 }
23 }
24
25 void* print1(void *a)
26 {
27 while (1)
28 {
29 pthread_mutex_lock(&mutex1);
30 pthread_cond_signal(&cond1);
31 pthread_cond_wait(&cond1, &mutex1);
32 pthread_mutex_unlock(&mutex1);
33 cout << "thread2 " << i++ << endl;
34 }
35 }
36
37 int main()
38 {
39 pthread_mutexattr_t mattr;
40 pthread_mutexattr_init(&mattr);
41 pthread_mutex_init(&mutex1, &mattr);
43 pthread_mutexattr_destroy(&mattr);
44
45 pthread_condattr_t cattr;
46 pthread_cond_init(&cond1, &cattr);
48 pthread_condattr_destroy(&cattr);
49
50 pthread_t t1;
51 pthread_t t2;
52
53 pthread_create(&t1, NULL, print0, NULL);
54 pthread_create(&t2, NULL, print1, NULL);
55 pthread_join(t1, NULL);
56 pthread_join(t2, NULL);
57
58 pthread_mutex_destroy(&mutex1);
60 pthread_cond_destroy(&cond1);
62 }
#include <iostream>
#include <pthread.h>
pthread_cond_t cond1;
pthread_mutex_t mutex1;
using namespace std;
int i = 0;
void* print0(void *a)
{
while(1)
{
pthread_mutex_lock(&mutex1);
pthread_cond_signal(&cond1);
pthread_cond_wait(&cond1, &mutex1);
cout << "thread1 " << i++ << endl;
pthread_mutex_unlock(&mutex1);
}
}
void* print1(void *a)
{
while (1)
{
pthread_mutex_lock(&mutex1);
pthread_cond_signal(&cond1);
pthread_cond_wait(&cond1, &mutex1);
pthread_mutex_unlock(&mutex1);
cout << "thread2 " << i++ << endl;
}
}
int main()
{
pthread_mutexattr_t mattr;
pthread_mutexattr_init(&mattr);
pthread_mutex_init(&mutex1, &mattr);
pthread_mutexattr_destroy(&mattr);
pthread_condattr_t cattr;
pthread_cond_init(&cond1, &cattr);
pthread_condattr_destroy(&cattr);
pthread_t t1;
pthread_t t2;
pthread_create(&t1, NULL, print0, NULL);
pthread_create(&t2, NULL, print1, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_mutex_destroy(&mutex1);
pthread_cond_destroy(&cond1);
}
class Token {
int token;
}
public class Solution{
static class Task implements Runnable{
int id;
int counter;
Token tk;
public Task( int id,int counter,Token tk){
this.id=id;
this.counter=counter;
this.tk=tk;
}
public void run() {
while(true){
synchronized (tk) {
if(tk.token == id){
if(id==0){
counter+=2;
System.out.println(counter);
tk.token=1;
}else if(id==1){
tk.token=0;
counter+=2;
System.out.println(counter);
}
tk.notify();
}else{
try {
tk.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
public static void main(String args[]){
Token tk = new Token();
tk.token=0;
Thread t1 = new Thread(new Task(0, 0,tk));t1.start();
Thread t2 = new Thread(new Task(1, 1,tk));t2.start();
try {
t1.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#define THREAD_NUM 2
sem_t semEven;
sem_t semOdd;
void* printEven(void* arg){
int i = 0;
while(i<100){
sem_wait(&semEven);
printf("%d ", i);
i+=2;
sem_post(&semOdd);
}
}
void* printOdd(void* arg){
int i = 1;
while(i<100){
sem_wait(&semOdd);
printf("%d ", i);
i+=2;
sem_post(&semEven);
}
}
int main(){
pthread_t th[THREAD_NUM];
sem_init(&semEven, 0, 1);
sem_init(&semOdd, 0, 0);
pthread_create(&th[0], NULL, printEven, NULL);
pthread_create(&th[1], NULL, printOdd, NULL);
pthread_join(th[0], NULL);
pthread_join(th[1], NULL);
sem_destroy(&semEven);
sem_destroy(&semOdd);
return 0;
}
I don't know how to implement multi thread in C, following is Java code:
public class EvenOdd {
private static final int LIMIT = 20;
private int num = 0;
//method
public synchronized void printEven(){
while(num < LIMIT){
while((num & 1) == 1){
try{
wait();
} catch(InterruptedException e){
e.printStackTrace();
}
}
System.out.print(num + " ");
++num;
notify();
}
}
public synchronized void printOdd(){
while(num < LIMIT){
while((num & 1) == 0){
try{
wait();
} catch(InterruptedException e){
e.printStackTrace();
}
}
System.out.print(num + " ");
++num;
notify();
}
}
//work class that prints num
static class PrintEven implements Runnable{
private EvenOdd eo;
public PrintEven(EvenOdd eo){
this.eo = eo;
}
@Override
public void run() {
eo.printEven();
}
}
static class PrintOdd implements Runnable{
private EvenOdd eo;
public PrintOdd(EvenOdd eo){
this.eo = eo;
}
@Override
public void run() {
eo.printOdd();
}
}
//test
public static void main(String args[]){
EvenOdd eo = new EvenOdd();
new Thread(new PrintEven(eo)).start();
new Thread(new PrintOdd(eo)).start();
}
}
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
pthread_mutex_t mutex_var = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond_var1 = PTHREAD_COND_INITIALIZER;
pthread_cond_t cond_var2 = PTHREAD_COND_INITIALIZER;
pthread_cond_t cond_var3 = PTHREAD_COND_INITIALIZER;
void *function1();
void *function2();
void *function3();
int count = 0;
int main()
{
pthread_t thread1,thread3,thread2;
pthread_create(&thread1,NULL,function1,NULL);
pthread_create(&thread3,NULL,function3,NULL);
pthread_create(&thread2,NULL,function2,NULL);
pthread_join(thread1,NULL);
pthread_join(thread2,NULL);
pthread_join(thread3,NULL);
exit(0);
}
void *function1()
{
for(; ;)
{
pthread_mutex_lock(&mutex_var);
if(count%2 != 0)
{
pthread_cond_wait(&cond_var1,&mutex_var);
}
count++;
printf("\nCounter value function-1: %d",count);
pthread_cond_signal( &cond_var2 );
if ( count >= 10 ) {
pthread_mutex_unlock( &mutex_var );
return(NULL);
}
pthread_mutex_unlock( &mutex_var );
}
}
void *function2()
{
for(;;)
{
pthread_mutex_lock(&mutex_var);
if(count%2 == 0)
{
pthread_cond_wait(&cond_var3,&mutex_var);
}
count++;
printf("\nCounter value function-2: %d\n",count);
pthread_cond_signal( &cond_var1 );
if ( count >= 10 ) {
pthread_mutex_unlock( &mutex_var );
return(NULL);
}
pthread_mutex_unlock( &mutex_var );
}
}
void *function3()
{
int n,sig=0;
int found =1;
for(;;)
{
pthread_mutex_lock(&mutex_var);
if(sig != 0)
{
pthread_cond_wait(&cond_var2,&mutex_var);
sig = 0;
}
sig = 1;
for(n=2;n<count/2;n++)
{
if( count%n == 0)
found=0;
}
if(found)
{
printf("::::Prime number\n");
}
found = 1;
pthread_cond_signal( &cond_var3 );
if( count >= 10)
{
pthread_mutex_unlock( &mutex_var );
return(NULL);
}
pthread_mutex_unlock( &mutex_var );
}
}
#include <stdio.h>
#include <pthread.h>
static int global;
pthread_t thread1,thread2;
void *even_fun (void *arg)
{
int local;
local = global;
if(local % 2 == 0)
{
printf("%d ",local);
global = global++;
}
pthread_exit(&global);
}
void *odd_fun (void *arg)
{
int local;
local = global;
if(local % 2 == 1)
{
printf("%d ",local);
global = global++;
}
pthread_exit(&global);
}
main()
{
int ret,arg,res;
void *retval;
#include <stdio.h>
#include <pthread.h>
static int global;
pthread_t thread1,thread2;
void *even_fun (void *arg)
{
int local;
local = global;
if(local % 2 == 0)
{
printf("%d ",local);
global = global++;
}
pthread_exit(&global);
}
void *odd_fun (void *arg)
{
int local;
local = global;
if(local % 2 == 1)
{
printf("%d ",local);
global = global++;
}
pthread_exit(&global);
}
main()
{
int ret,arg,res;
void *retval;
do{
ret = pthread_create (&thread1,NULL,even_fun,&arg);
pthread_join(thread1,&retval);
res = pthread_create (&thread2,NULL,odd_fun,&arg);
pthread_join(thread2,&retval);
}while(global < 100);
}
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex mtx;
std::condition_variable cv;
bool doPrintOdd = false;
bool doPrintEven= true;
int nMax = 100;
void printOdd() {
for (int i = 0; i < nMax; ++i) {
std::unique_lock<std::mutex> lck(mtx);
while (!doPrintOdd) cv.wait(lck);
std::cout << 2 * i + 1 << std::endl;
doPrintOdd = false;
doPrintEven = true;
cv.notify_one();
}
}
void printEven() {
for (int i = 0; i < nMax; ++i) {
std::unique_lock<std::mutex> lck(mtx);
while (!doPrintEven) cv.wait(lck);
std::cout << 2 * i << std::endl;
doPrintEven = false;
doPrintOdd = true;
cv.notify_one();
}
}
int main() {
std::thread t1(printOdd);
std::thread t2(printEven);
t1.join();
t2.join();
std::cout << "Press Enter to continue ..." << std::endl;
std::cin.get();
return 0;
}
public class ThreadImpl implements Runnable {
public int i;
{
i=1;
}
@Override
public void run() {
while(i<10)
{
if(Thread.currentThread().getName().equalsIgnoreCase("even"))
{
if(i%2==0)
{
printEvenNumbers();
}
else
{
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
else if(Thread.currentThread().getName().equalsIgnoreCase("odd")&&i%2==1){
printOddNumbers(); }
}}
public void printEvenNumbers(){
System.out.println("Thread in printEven()"+Thread.currentThread().getName()+" "+i);
i++;}
public void printOddNumbers() {
System.out.println("Thread in printOdd() "+Thread.currentThread().getName()+" "+i);
i++;
synchronized (this) {
notify(); }}
public static void main(String[] args) {
ThreadImpl r = new ThreadImpl();
Thread even = new Thread(r);
Thread odd = new Thread(r);
even.setName("even");
odd.setName("odd");
odd.start();
even.start(); }
#include <pthread.h>
#include <stdio.h>
//#include <>
int count = 0;
pthread_mutex_t lock;
void *func(void* arg)
{
unsigned long i = (unsigned long)(arg);
while(1)
{
if(i == 0) while(count % 2 == 0);
if(i == 1) while(count % 2 != 0);
pthread_mutex_lock(&lock);
printf("%d\n", count++);
pthread_mutex_unlock(&lock);
}
}
int main()
{
int i = 0;
//pthread_t t1, t2;
pthread_mutex_init(&lock, NULL);
for(i = 0; i < 2; i++)
{
pthread_t t;
pthread_create(&t, 0, func, (void*)i);
}
for(;;);
// pthread_cond_wait
}
Is there really a need for locking?
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#define LIMIT 100
int counter;
void* function(void *p)
{
int expected = *(int *)p;
while(expected < LIMIT) {
while (counter != expected);
printf("%d\n", counter++);
expected += 2;
};
exit(0);
}
int main(int argc, char *argv[])
{
pthread_t thread1, thread2;
int counter = 0;
int expected_0 = 0, expected_1 = 1;
pthread_create(&thread1, NULL, function, (void *)&expected_0);
pthread_create(&thread2, NULL, function, (void *)&expected_1);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
return 0;
}
There is a tiny bug, in the main function
int counter = 0;
should be
counter = 0;
I meant to initialise the global variable. It works however because globals are set to 0. That line is just unnecessary.
Here's a solution using java.util.SynchronousQueue,
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;
public class EvenOddThreads {
public static void demoUsingJUC() {
final BlockingQueue<Boolean> queue = new SynchronousQueue<Boolean>();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i += 2) {
try {
if (i > 0 && queue.take()) {
System.out.println(i);
} else {
System.out.println(i);
}
queue.put(true);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i < 10; i += 2) {
try {
if (queue.take()) {
System.out.println(i);
queue.put(true);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t1.start();
t2.start();
}
public static void main(String[] args) {
demoUsingJUC();
}
}
Solution using C++ 11 threads
// CPP_11_Threading.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream> // std::cout
#include <thread>
#include <vector>
#include <mutex>
#include <atomic>
std::mutex mutex;
std::atomic<int> state = 1; // 1 = wrote ODD 2 = wrote EVEN
void EvenThreadFunction()
{
for (int i = 0; i <= 100; i = i + 2)
{
while (state != 1)
{
// some delay before we check flag again.
std::chrono::milliseconds dura(2);
std::this_thread::sleep_for(dura);
}
{
mutex.lock();
std::cout << "Even : " << i << std::endl;
mutex.unlock();
state = 0;
}
// purposeful delay introduced.
std::chrono::milliseconds dura(50);
std::this_thread::sleep_for(dura);
}
}
void OddThreadFunction()
{
for (int i = 1; i <= 100; i = i + 2)
{
while (state != 0)
{
// some delay before we check flag again.
std::chrono::milliseconds dura(2);
std::this_thread::sleep_for(dura);
}
{
mutex.lock();
std::cout << "Odd : " << i << std::endl;
mutex.unlock();
state = 1;
}
// purposeful delay introduced to add a-synchronization.
std::chrono::milliseconds dura(10);
std::this_thread::sleep_for(dura);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
std::thread first(OddThreadFunction);
std::thread second(EvenThreadFunction);
// synchronize threads:
first.join(); // pauses until first finishes
second.join(); // pauses until second finishes
return 0;
}
GLC@GLC-Butterfly ~
$ cat pthread1.cpp
#include <iostream>
#include <pthread.h>
#include <iomanip>
using namespace std;
pthread_mutex_t mutexid=PTHREAD_MUTEX_INITIALIZER;
int prevthread=1;
void* printValue(void *arg){
int remainder=(int)(arg);
int i=0;
while(i<10) {
if(prevthread != remainder) {
pthread_mutex_lock(&mutexid);
if(i++%2==remainder) {
cout<<i-1 <<" ";
}
pthread_mutex_unlock(&mutexid);
prevthread=1-prevthread;
}
}
cout.flush();
}
int main()
{
pthread_t threadid1,threadid2;
pthread_create(&threadid1, NULL, printValue,(void*)1);
pthread_create(&threadid2, NULL, printValue,(void*)0);
pthread_join(threadid1,NULL);
pthread_join(threadid2,NULL);
pthread_exit(0);
}
GLC@GLC-Butterfly ~
$ g++ -pthread -fpermissive pthread1.cpp
pthread1.cpp: In function ‘void* printValue(void*)’:
pthread1.cpp:10:25: warning: cast from ‘void*’ to ‘int’ loses precision [-fpermissive]
int remainder=(int)(arg);
^
GLC@GLC-Butterfly ~
$ ./a.exe
0 1 2 3 4 5 6 7 8 9
GLC@GLC-Butterfly ~
$
How about this piece of code
global variables:
============
bool flag = TRUE;
int value = 0;
Thread 1:
=======
while(1)
{
if(flag)
{
printf("%d\n", value++);
flag = !flag;
}
}
Thread 2:
=======
while(1)
{
if(!flag)
{
printf("%d\n",value++);
flag = !flag;
}
}
Output:
0 (by Thread 1)
1 (by Thread 2)
2 (by Thread 1)
3 (by Thread 2)
4 (By Thread 1)
.
.
.
.
these above java implementation can only print numbers starting from 1. not printing 0 at begining
- vijay March 12, 2014