Qualcomm Interview Question
Country: India
Interview Type: In-Person
wouldn't waiting for mutex held by the other thread while holding another mutex the other thread may wait for be prone to deadlock? One mutex is sufficient.
use semaphore and global variable
int glob=0,mutex = 1,sem1=1,sem2=0
void func1()
{
down(sem1);
down(mutex);
if( glob %2 == 0 )
{
printf("thread 1");
glob++;
}
up(mutex);
up(sem2);
}
void func2()
{
down(sem2);
down(mutex);
if( glob%2 != 0 ){
printf("thread2");
glob++;
}
up(sem1);
up(mutex);
}
main()
{
pthread_create(func1) //not all arguments are shown
pthread_create(func2)
while(1) ;
}
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#define MAX_THREADS 2
#define INVALID_RETURN_VALUE (-1)
int shared_count = 0;
pthread_mutex_t shared_count_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t shared_count_cv = PTHREAD_COND_INITIALIZER;
void
thread_1(void *ptr)
{
char thread_name[15];
pthread_setname_np("even_thread");
pthread_getname_np(pthread_self(), thread_name, 15);
while (1) {
sleep(1);
pthread_mutex_lock(&shared_count_lock);
while (!((shared_count - 1) % 2)) {
pthread_cond_wait(&shared_count_cv, &shared_count_lock);
shared_count++;
printf("Thread_name = %s shared_count = %d\n", thread_name,
shared_count);
}
pthread_cond_signal(&shared_count_cv);
pthread_mutex_unlock(&shared_count_lock);
}
}
void
thread_2(void *ptr)
{
char thread_name[15];
pthread_setname_np("odd_thread");
pthread_getname_np(pthread_self(), thread_name, 15);
while (1) {
sleep(1);
pthread_mutex_lock(&shared_count_lock);
while (!(shared_count % 2)) {
pthread_cond_wait(&shared_count_cv, &shared_count_lock);
shared_count++;
printf("Thread_name = %s shared_count = %d\n", thread_name,
shared_count);
}
pthread_cond_signal(&shared_count_cv);
pthread_mutex_unlock(&shared_count_lock);
}
}
int
main(int argc, char **argv)
{
int i;
int rc = INVALID_RETURN_VALUE;
pthread_t thread[MAX_THREADS];
pthread_t thread2;
char thread_name[10];
pthread_setname_np("main");
pthread_getname_np(pthread_self(), thread_name, 10);
pthread_create(&thread[0], NULL, (void *) &thread_1, NULL);
pthread_create(&thread[1], NULL, (void *) &thread_2, NULL);
for(i = 0; i < MAX_THREADS; i++) {
pthread_join(thread[i], NULL);
}
/*
* Cleanup
*/
rc = pthread_mutex_destroy(&shared_count_lock);
if (rc) {
printf("Unable to destroy lock = %s\n", thread_name);
}
rc = pthread_cond_destroy(&shared_count_cv);
if (rc) {
printf("Unable to destroy cv = %s\n", thread_name);
}
return 0;
}
/* compile and execute this programme on linux plateform gcc programme_name -l pthread */
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
int count =0;
int flag1=0;
void *fun1(void *);
void *fun2(void *);
int main()
{
pthread_t id1,id2;
pthread_create (&id1,NULL,&fun1,NULL);
pthread_create (&id2,NULL,&fun2,NULL);
pthread_join(id1,NULL);
pthread_join(id2,NULL);
return 0;
}
void *fun1(void *p)
{
for(;count<10;)
{
if(flag1 ==0)
{
printf ("%d ",count++);
flag1=1;
}
}
}
void *fun2(void *p)
{
for(;count<10;)
{
if(flag1 ==1)
{
printf ("%d ",count++);
flag1=0;
}
}
}
/*end of programme*/
public class PrintAlternateWithTwoThread
{
Object lock = new Object();
public void firstMethod()
{
synchronized (lock)
{
for (int i = 0; i < 10; i++)
{
try
{
if (i % 2 == 0)
{
System.out.println("I " + i);
}
lock.wait();
}
catch (final InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
lock.notify();
}
}
}
public void secondMethod()
{
synchronized (lock)
{
for (int i = 0; i < 10; i++)
{
try
{
if (i % 2 != 0)
{
System.out.println("I " + i);
}
lock.notify();
lock.wait();
}
catch (final InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static void main(final String[] args)
{
final PrintAlternateWithTwoThread t = new PrintAlternateWithTwoThread();
final Thread t1 = new Thread(new Runnable()
{
@Override
public void run()
{
t.firstMethod();
}
});
final Thread t2 = new Thread(new Runnable()
{
@Override
public void run()
{
t.secondMethod();
}
});
t1.start();
t2.start();
try
{
t1.join();
t2.join();
}
catch (final InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
#include <thread>
#include <mutex>
#include <condition_variable>
#include <iostream>
BOOST_AUTO_TEST_CASE( PrintInSequenceTest )
{
unsigned i = 0;
const unsigned to = 10;
std::mutex mutex;
std::condition_variable cv;
auto process = [&] ( std::function< bool( int ) >&& functor )
{
for ( ;; )
{
std::unique_lock< std::mutex > lock( mutex );
while ( functor( i ) )
cv.wait( lock );
std::cout << i++ << ' ';
auto mustBreak = i >= to;
cv.notify_one();
if ( mustBreak )
break;
}
};
std::cout.sync_with_stdio( false );
std::thread oddThread( [&]{ process( [] ( int i ){ return ( i & 1 ) == 0; } ); } );
std::thread evenThread( [&]{ process( [] ( int i ){ return ( i & 1 ) != 0; } ); } );
oddThread.join();
evenThread.join();
std::cout << std::endl;
}
typedef enum { Even, Odd, None } Turn;
int count = 0;
Turn turn = None;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t condition = PTHREAD_COND_INITIALIZER;
void *even (void *args)
{
while(1)
{
pthread_mutex_lock(&lock);
while(turn != Even)
pthread_cond_wait(&condition, &lock);
printf("even %d\n", count++);
turn = Odd;
pthread_cond_broadcast(&condition);
pthread_mutex_unlock(&lock);
}
}
void *odd (void *args)
{
while(1)
{
pthread_mutex_lock(&lock);
while(turn != Odd)
pthread_cond_wait(&condition, &lock);
printf("odd %d\n", count++);
turn = Even;
pthread_cond_broadcast(&condition);
pthread_mutex_unlock(&lock);
}
}
int main ()
{
char buf[32];
pthread_t t1,t2;
pthread_create(&t2, NULL, odd, NULL);
pthread_create(&t1, NULL, even, NULL);
sleep(1);
pthread_mutex_lock(&lock);
printf("Start\n");
sleep(1);
turn = Even;
pthread_cond_broadcast(&condition);
pthread_mutex_unlock(&lock);
printf("Enter \"end\" to end...\n");
while(strcmp(gets(buf), "end") != 0);
return 0;
}
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
int shared_num=0;
pthread_mutex_t t_mutex;
void *print_even_nos(void *ptr);
void *print_odd_nos(void *ptr);
int main (
void)
{
pthread_t tid[2];
pthread_create(&tid[0], 0, &print_even_nos, 0);
pthread_create(&tid[1], 0, &print_odd_nos, 0);
pthread_join(tid[0], NULL);
pthread_join(tid[1], NULL);
return 0;
}
void *print_even_nos(
void *ptr)
{
while (1) {
pthread_mutex_lock(&t_mutex);
if (shared_num > 100) {
pthread_mutex_unlock(&t_mutex);
break;
}
if ((shared_num % 2)==0) {
printf("even thread = [%d]\n", shared_num);
shared_num++;
}
pthread_mutex_unlock(&t_mutex);
};
return NULL;
}
void *print_odd_nos(
void *ptr)
{
while (1) {
pthread_mutex_lock(&t_mutex);
if (shared_num > 100) {
pthread_mutex_unlock(&t_mutex);
break;
}
if ((shared_num % 2) == 1) {
printf("odd thread = [%d]\n", shared_num);
shared_num++;
}
pthread_mutex_unlock(&t_mutex);
};
return NULL;
}
#include <iostream>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int cnt= 0;
int flag = 0;
const int MAX = 10;
void *functionCount1(void*);
void *functionCount2(void*);
int main(int argc, char *argv[])
{
pthread_t thread1, thread2;
/* Create independent threads each of which will execute function */
pthread_create( &thread1, NULL, &functionCount1, NULL);
pthread_create( &thread2, NULL, &functionCount2, NULL);
//pthread_join( thread1, NULL);
pthread_join( thread2, NULL);
exit(0);
return 0;
}
void *functionCount1(void*p)
{
for(;cnt< 10;)
{
if(flag == 0)
{
cout<<"thread1 "<<cnt++<<endl;
flag = 1;
}
}
return NULL;
}
void *functionCount2(void *p)
{
for(;cnt<10;)
{
if(flag == 1)
{
cout<<"thread2 "<<cnt++<<endl;
flag = 0;
}
}
return NULL;
}
void *functionCount2(void *p)
{
for(;cnt<10;)
{
if(flag == 1)
{
cout<<"thread2 "<<cnt++<<endl;
flag = 0;
}
}
return NULL;
}
Just curious.. there can be a case in this code when a thread is checking the value of flag and another thread is modifying the flag value...
since the flag modifying operation is not atomic, so it can be interrupted in the middle by the system, and if another thread tries to read the flag value, then it can behave weirdly. Rigght?
#include <pthread.h>
- TAK October 06, 2013#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
int glob = 0;
sem_t mutex1;
sem_t mutex2;
void function1(void)
{
static int count1 = 0;
while(count1 < 100){
sem_wait(&mutex1);
glob ++;
printf("%d \n", glob);
sem_post(&mutex2);
count1++;
}
}
void function2(void)
{
static int count1 = 0;
while(count1 < 100){
sem_wait(&mutex2);
glob ++;
printf("%d \n", glob);
sem_post(&mutex1);
count1++;
}
}
main()
{
int rc1, rc2;
pthread_t thread1, thread2;
sem_init(&mutex1, 0, 1);
sem_init(&mutex2, 0, 0);
/* Create independent threads each of which will execute functionC */
if( (rc1=pthread_create( &thread1, NULL, &function1, NULL)) )
{
printf("Thread creation failed: %d\n", rc1);
}
if( (rc2=pthread_create( &thread2, NULL, &function2, NULL)) )
{
printf("Thread creation failed: %d\n", rc2);
}
/* Wait till threads are complete before main continues. Unless we */
/* wait we run the risk of executing an exit which will terminate */
/* the process and all threads before the threads have completed. */
pthread_join( thread1, NULL);
pthread_join( thread2, NULL);
exit(0);
}