I'm learning multi-threading and trying to create a program that can print two strings alternately.
I have written the following code :
#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
pthread_mutex_t lock;
void print(char a[50]){
pthread_mutex_lock(&lock);
printf("%s", a); //output console is the shared resource
sleep(2);
pthread_mutex_unlock(&lock);
}
void* hello(void* status){
while(*((char*)status) != '\n'){
print("Hello World\n");
}
}
void* bye(void* status){
while(*((char*)status) != '\n'){
print("Goodbye World\n");
}
}
int main(){
pthread_t id1, id2;
char status = '\0';
int state;
if (pthread_mutex_init(&lock, NULL) != 0) {
printf("\n mutex init has failed\n");
exit(1);
}
printf("Starting Threads (Press Enter to terminate)\n");
state = pthread_create(&id1, NULL, hello, &status);
if(state != 0){
printf("Could not create thread, exiting.\n");
exit(1);
}
state = pthread_create(&id2, NULL, bye, &status);
if(state != 0){
printf("Could not create thread, exiting.\n");
exit(1);
}
scanf("%c", &status);
printf("Out of The Threads\n");
pthread_mutex_destroy(&lock);
return 0;
}
According to what I understand, the mutex should lock the print function once for the hello function and then for the bye function. But I only get this output:
Starting Threads (Press Enter to terminate)
Hello World
Hello World
Hello World
Hello World
Hello World
Why does only the hello function get allocated the print function? How do I get it do print both?
Because, you use infinitive while in each function hello and bye. When the first thread starts, it never exits the while loop unless you press enter.
But when you type enter, the loop conditions in all functions will be false, so two threads will never touch print function again.
OT, you forget to join the threads.
Try to delete the while loop in each function and use it in main function, and see what happen. For example the program below (it may be not optimized, but i just want to show why your program always print Hello World:
#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
pthread_mutex_t lock;
void print(char a[50]){
pthread_mutex_lock(&lock);
printf("%s", a); //output console is the shared resource
sleep(2);
pthread_mutex_unlock(&lock);
}
void* hello(void* status){
// while(*((char*)status) != '\n'){
print("Hello World\n");
//}
}
void* bye(void* status){
//while(*((char*)status) != '\n'){
print("Goodbye World\n");
// }
}
int main(){
pthread_t id1, id2;
char status = '\0';
int state;
if (pthread_mutex_init(&lock, NULL) != 0) {
printf("\n mutex init has failed\n");
exit(1);
}
printf("Starting Threads (Press Enter to terminate)\n");
while(status != '\n') {
state = pthread_create(&id1, NULL, hello, &status);
if(state != 0){
printf("Could not create thread, exiting.\n");
exit(1);
}
state = pthread_create(&id2, NULL, bye, &status);
if(state != 0){
printf("Could not create thread, exiting.\n");
exit(1);
}
pthread_join(id1, NULL);
pthread_join(id1, NULL);
scanf("%c", &status);
}
printf("Out of The Threads\n");
pthread_mutex_destroy(&lock);
return 0;
}
Related
HI I am writing a program which write the string in file, process 1 will write a small letters in file and process 2 write a capital letters in same file. i implemented a program using threading, process 1 must run first, after that run the process 2 . program as follows.
/******************
* Header Files
******************/
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
pthread_mutex_t lock;
void* write_p1()
{
if((pthread_mutex_lock(&lock)) != 0)
{
printf("pthread_mutex_lock() failed\n");
exit(1);
}
int index=0; /*used in for loop*/
int flag=0; /*flag used in capital letter and space detecion*/
FILE *fp=NULL; /*file pointer used to store open file*/
char str[100]; /*to store user string*/
printf("*****Hi, I am Process 1*****\n");
/*open the sample.txt file for write*/
fp=fopen("sample.txt","w");
if(fp==NULL)
{
printf("Not able to open file\n");
exit(1);
}
printf("Enter small letters\n");
fgets(str,100,stdin);
/*capital letter and space detection*/
if((strlen(str)>0)&&(str[strlen(str)-1]=='\n'))
{
str[strlen(str)-1]='\0';
}
for(index=0;str[index]!='\0';index++)
{
if(islower(str[index]) || str[index] == ' ')
{
flag=0;
}
else
{
printf("Enter Small Letters\n");
exit(1);
}
}
if(flag==0)
{
fprintf(fp,"%s",str);
}
/*close the file*/
fclose(fp);
printf("Entered string: %s\n",str);
if((pthread_mutex_unlock(&lock)) != 0)
{
printf("pthread_mutex_unlock() failed\n");
exit(1);
}
printf("\n\n");
}
void* write_p2()
{
if((pthread_mutex_lock(&lock)) != 0)
{
printf("pthread_mutex_lock() failed\n");
exit(1);
}
int index=0; /*used in for loop*/
int flag=0; /*flag used in small letter and space detecion*/
FILE *fp=NULL; /*file pointer used to store open file*/
char str[100]; /*to store user string*/
printf("*****Hi, I am Process 2*****\n");
/*open the sample.txt file for write*/
fp=fopen("sample.txt","a");
if(fp==NULL)
{
printf("Not able to open file\n");
exit(1);
}
printf("Enter Capital letters\n");
fgets(str,100,stdin);
/*capital letter and space detection*/
if((strlen(str)>0)&&(str[strlen(str)-1]=='\n'))
{
str[strlen(str)-1]='\0';
}
for(index=0;str[index]!='\0';index++)
{
if(isupper(str[index]) || str[index] == ' ')
{
flag=0;
}
else
{
printf("Enter capital Letters\n");
exit(1);
}
}
if(flag==0)
{
fprintf(fp,"%s",str);
}
/*close the file*/
fclose(fp);
printf("Entered string: %s\n",str);
if((pthread_mutex_unlock(&lock)) != 0)
{
printf("pthread_mutex_unlock() failed\n");
exit(1);
}
printf("\n\n");
}
int main(void)
{
/*initialized semaphore*/
if((pthread_mutex_init(&lock,NULL)) != 0)
{
printf("pthread_mutex_init() failed\n");
exit(1);
}
/*create a two thread*/
pthread_t t1=0,t2=0;
pthread_create(&t1,NULL,write_p1,NULL);
pthread_create(&t2,NULL,write_p2,NULL);
/*this function wait for thread to terminate*/
pthread_join(t1,NULL);
pthread_join(t2,NULL);
/*destroy the semaphore*/
if((pthread_mutex_destroy(&lock)) != 0)
{
printf("pthread_mutex_destroy() failed\n");
exit(1);
}
return 0;
}
Now This program is working but sometime it will run first thread 2(process 2) or some time thread 1(process 1) , i need a solution for that, it must run thread 1(process 1) first after that thread 2(process 2), so what changes should i do?
I am wring below program for you. You can do it by using conditional variable. Implement same procedure in your code. How will it work? To start the controlling process, we allowing thread1 first. In the main thread (i.e. main function; every program has one main thread, in C/C++ this main thread is created automatically by the operating system once the control passes to the main method/function via the kernel) we are calling pthread_cond_signal(&cond1);. Once this function is called from the main thread, thread1, which was waiting on cond1, will be released and it will start executing further. Once it finishes its final task, it will call pthread_cond_signal(&cond2);. Now, the thread which was waiting on condition cond2, i.e. thread2, will be released and it will start to execute its final stage
#include<pthread.h>
pthread_cond_t cond1 = PTHREAD_COND_INITIALIZER;
pthread_cond_t cond2 = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t lock2 = PTHREAD_MUTEX_INITIALIZER;
int TRUE = 1;
void * threadMethod1(void *arg)
{
printf("In thread1\n");
do{
pthread_mutex_lock(&lock1);
//Add your business logic(parallel execution codes) here
pthread_cond_wait(&cond1, &lock1);
printf("I am thread1 generating the final report and inserting into file \n");
pthread_cond_signal(&cond2);/* Now allow 2nd thread to process */
pthread_mutex_unlock(&lock1);
}while(TRUE);
pthread_exit(NULL);
}
void * threadMethod2(void *arg)
{
printf("In thread2\n");
do
{
pthread_mutex_lock(&lock2);
//Add your business logic(parallel execution codes) here
pthread_cond_wait(&cond2, &lock2);
printf("I am thread2 generating the final report and inserting into a file \n");
pthread_cond_signal(&cond1);
pthread_mutex_unlock(&lock2);
}while(TRUE);
pthread_exit(NULL);
}
int main(void)
{
pthread_t tid1, tid2;
int i = 0;
printf("Before creating the threads\n");
if( pthread_create(&tid1, NULL, threadMethod1, NULL) != 0 )
printf("Failed to create thread1\n");
if( pthread_create(&tid2, NULL, threadMethod2, NULL) != 0 )
printf("Failed to create thread2\n");
pthread_cond_signal(&cond1);/* Now allow first thread to process first */
sleep(1);
TRUE = 0;/* Stop all the thread */
//sleep(3);
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
exit(0);
}
I have a problem connected with producers and consumers. I have 1 producer and 3 consumers. Producer produce letters which i put in my queue, and consumers take this letters. It is considered that letter has been removed from the queue, when 2 of consumers took it, but there is an option, that consumer A and consumer C can't take the same letter(it's possible that con. A will take letter first, then con. B will take it second or con. B first, then con C(or A) second, but no possibility when A and C together).
I wrote a code solving this problem, but now I can't print enything from functions.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include "FIFO.h"
#define semaphore sem_t
#define MAX_SIZE _SIZE
#define SLEEP 1
#define true 1
FIFO buff;
semaphore full, empty, a_read, b_read, c_read, mutex;
void randSleep(int max) {
double x = rand()/(double)RAND_MAX;
usleep( (int)floor( x*max ) );
}
void* producer_func()
{
char c='A';
while(GetAmount(&buff)<MAX_SIZE)
{
sem_wait(&empty);
sem_wait(&mutex);
Push(&buff, c);
sem_post(&mutex);
sem_post(&full);
randSleep(SLEEP);
}
pthread_exit(NULL);
}
void* consumer_a_func()
{
char c;
long int first_met;
while(true)
{
sem_wait(&a_read);
sem_wait(&full);
if (sem_getvalue(&b_read,&first_met)) printf("Error with returning b_read value");
sem_wait(&mutex);
if (first_met)
{
c = First(&buff);
sem_post(&mutex);
}
else
{
c = Pop(&buff);
sem_post(&mutex);
sem_post(&a_read);
sem_post(&b_read);
sem_post(&empty);
}
//printf("c value %s\n", c);
randSleep(SLEEP);
}
pthread_exit(NULL);
}
void* consumer_b_func()
{
char c;
long int first_met_a, first_met_c ;
while(true)
{
sem_wait(&b_read);
sem_wait(&full);
if (sem_getvalue(&a_read,&first_met_a)) printf("Error with returning a_read value");
if (sem_getvalue(&c_read,&first_met_c)) printf("Error with returning c_read value");
sem_wait(&mutex);
if (first_met_a && first_met_c)
{
c = First(&buff);
sem_post(&mutex);
}
else
{
c = Pop(&buff);
sem_post(&mutex);
sem_post(&b_read);
if (first_met_a)
sem_post(&c_read);
else
sem_post(&a_read);
sem_post(&empty);
}
//printf("c value %s\n", c);
randSleep(SLEEP);
}
pthread_exit(NULL);
}
void* consumer_c_func()
{
char c;
long int first_met;
while(true)
{
sem_wait(&c_read);
sem_wait(&full);
if (sem_getvalue(&b_read,&first_met)) printf("Error with returning b_read value");
sem_wait(&mutex);
if (first_met)
{
c = First(&buff);
sem_post(&mutex);
}
else
{
c = Pop(&buff);
sem_post(&mutex);
sem_post(&c_read);
sem_post(&b_read);
sem_post(&empty);
}
printf("c value %s\n", c);
randSleep(SLEEP);
}
pthread_exit(NULL);
}
int main()
{
Init(&buff);
sem_init(&empty, 0, MAX_SIZE);
sem_init(&full, 0, 0);
sem_init(&a_read, 0, 1);
sem_init(&b_read, 0, 1);
sem_init(&c_read, 0, 1);
sem_init(&mutex, 0, 1);
pthread_t producer, consumer_a, consumer_b, consumer_c;
pthread_create(&producer, NULL, producer_func, NULL);
printf("All right\n");
pthread_create(&consumer_a, NULL, consumer_a_func, NULL);
printf("All right\n");
pthread_create(&consumer_b, NULL, consumer_b_func, NULL);
printf("All right\n");
pthread_create(&consumer_c, NULL, consumer_c_func, NULL);
printf("All right\n");
pthread_join(&producer, (void**)NULL);
pthread_join(&consumer_a, (void**)NULL);
pthread_join(&consumer_b, (void**)NULL);
pthread_join(&consumer_c, (void**)NULL);
}
files FIFO.h, FIFO.c
error looks like
In _IO_vfprintf_internal (s=0x7ffff78ac620 <_IO_2_1_stdout_>, format=, ap=ap#entry=0x7ffff6acfe58) at vfprintf.c:1632 ()
Or segmentation fault(core dumped)
But sometimes this code runs correctly, but without any printf's which i wrote in producer-consumer functions
//printf("c value %s\n", c);
c is a char, to print it you should use
printf("c value %c\n", c);
You can try to compile with -Wformat, so warning will happend if you use invalid format for variables in the printf calls.
I have this code, I am trying to create n threads, Do some work in each thread, and then reap each thread. If n thread is even, use detach, and if odd, use join,
When i run the program, it first prints out Successfully reaped thread, then doing working, then successfully reaped thread... looks like i have some synchronization issues
Do I even need to use Mutex?
Can anyone help me with getting everything running in the right order?
Thank you
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t lock;
void *dowork(){
//Do whatever needs to be done in each thread here
pthread_mutex_lock(&lock);
long tid = (long) pthread_self();
printf("Doing Work ...for %ld\n",tid);
pthread_mutex_unlock(&lock);
//pthread_exit(NULL);
return;
}
void spawn(int n){
if (pthread_mutex_init(&lock, NULL) != 0)
{
printf("\n mutex init failed\n");
exit (1);
}
int i=0;
//pthread_t * thread = malloc(sizeof(pthread_t)*n);
pthread_t threads[n];
while (i<n) {
if(pthread_create(&(threads[i]), NULL, dowork, NULL) != 0){
printf ("Create pthread error!\n");
exit (1);
}
i++;
}//End of while
// Wait for threads to complete //
i = 0;
while (i<n)
{
int success = -1;
if(i%2 == 0){
success=pthread_detach(threads[i]);
}
else{
success=pthread_join(threads[i], NULL);
}
if(success==0)
printf("Succesfully reaped thread\n");
i++;
}
pthread_mutex_destroy(&lock);
}
int main() {
spawn(5);
}
Hi im trying to implement faster cat than the one provided.
My current implementation looks like this:
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#define BUF_SIZE 1024*1024*1024
char buffer[BUF_SIZE];
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond_var = PTHREAD_COND_INITIALIZER;
pthread_cond_t cond_var2 = PTHREAD_COND_INITIALIZER;
int readed = 0;
/*
Read characters from standard input and saves them to buffer
*/
void *consumer(void *data) {
int r;
while(1) {
//---------CRITICAL CODE--------------
//------------REGION------------------
pthread_mutex_lock(&mutex);
if (readed > 0)
{
pthread_cond_wait(&cond_var2, &mutex);
}
r = read(0, buffer, BUF_SIZE);
readed = r;
pthread_cond_signal(&cond_var);
pthread_mutex_unlock(&mutex);
//------------------------------------
if (r == -1){
printf("Error reading\n");
}
else if (r == 0) {
pthread_exit(NULL);
}
}
}
/*
Print chars readed by consumer from standard input to standard output
*/
void *out_producer(void *data) {
int w;
while(1){
//---------CRITICAL CODE--------------
//-------------REGION-----------------
pthread_mutex_lock(&mutex);
if (readed == 0)
{
pthread_cond_wait(&cond_var, &mutex);
}
w = write(1, buffer, readed);
readed = 0;
pthread_cond_signal(&cond_var2);
pthread_mutex_unlock(&mutex);
//------------------------------------
if (w == -1){
printf("Error writing\n");
}
else if (w == 0) {
pthread_exit(NULL);
}
}
}
What would you suggest to make it faster?
Any ideas?
I was thinking about the BUF_SIZE, what would you think would be optimal size of buffer?
Main just makes the threads:
int main() {
// Program RETURN value
int return_value = 0;
// in - INPUT thread
// out - OUTPUT thread
pthread_t in, out;
// Creating in thread - should read from standard input (0)
return_value = pthread_create(&in , NULL, consumer, NULL);
if (return_value != 0) {
printf("Error creating input thread exiting with code error: %d\n", return_value);
return return_value;
}
// Creating out thread - should write to standard output (1)
return_value = pthread_create(&out, NULL, out_producer, NULL);
if (return_value != 0) {
printf("Error creating output thread exiting with code error: %d\n", return_value);
return return_value;
}
return_value = pthread_join(in, NULL);
return_value = pthread_join(out, NULL);
return return_value;
}
How exactly is adding threads to cat going to make it faster? You can't just throw parallelism at any program and expect it to run faster.
Cat basically just transports every line of input (usually from a file) to output. Since it's important that the lines are in order, you have to use mutual exclusion to avoid racing.
The upper bound of the speed (the fastest that cat can run) in parallel cannot be higher than cat in serial, since every thread must perform the serial actions, along with the cost of synchronization.
I have to wriete program
"Bring to life two threads. First thread must write char 'a' 30000
times second one 'b' 25000 times.
I wrote this program but i do not know this is a good result. I expect first see 30000 times a then b when I use pthread_join(p,NULL). My program write a and b randomaly it is good or not?
#include<stdio.h>
#include<string.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
pthread_t f,s;
void* a(void *arg)
{
int j;
for(j=0;j<30000;j++) printf("a\n");
return NULL;
}
void* b(void *arg)
{
int u;
for(u=0;u<25000;u++) printf("b\n");
return NULL;
}
int main(void)
{
int i = 0;
int err;
err = pthread_create(&f, NULL, &a, NULL);
if (err != 0)
printf("\ncan't create thread :[%s]", strerror(err));
else
printf("\n Thread created successfully\n");
err = pthread_create(&s, NULL, &b, NULL);
if (err != 0)
printf("\ncan't create thread :[%s]", strerror(err));
else
printf("\n Thread created successfully\n");
pthread_join(f, NULL);
sleep(5);
return 0;
}