Hey so I'm trying to create a multithreaded program. The first thread takes in input from std in and stores it in a minheap. The second thread... well for now, all it does is print "sequencer thread works" and nothing else because it doesn't run properly.
Both threads are detached, so they should run simultaneously, and yet for some reason the second thread doesn't run until the first exits. Is it something simple I am overlooking? I'm new to multithreading.
Thanks
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
#include "MinHeap.h"
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void* readerthread(MinHeap minheap, char eventlist[], char timestamp[])
{
char buffer[100];
char input;
int ret, len, fd;
while(1)
{
char *choice;
choice = malloc(50*sizeof(char));
fgets(choice, 50, stdin);
printf("choice = : %s", choice);
if(checkTimestamp(choice)==0)
{
pthread_mutex_lock(&mutex);
addElement(&minheap, choice);
pthread_mutex_unlock(&mutex);
}
free(choice);
printf( "min of minheap: %s\n", getMin(&minheap));
}
void* sequencerthread()
{
printf("sequencer works\n");
fflush(stdout);
pthread_exit(0);
}
int main(int argc, char *argv[])
{
if (argv < 2)
{
printf("not enough arguments. exiting...\n");
return 1;
}
char timestamp[50];
char event[50];
char eventlist[sizeof(char)+170];
int i;
char nowtimestamp[] = "2400/001/00/00/00";
MinHeap minheap;
initializeMinHeap(&minheap, intCompare, sizeof(char)*50);
strcpy(timestamp, argv[1]);
strcpy(event, argv[2]);
pthread_t ignore1, ignore2;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
pthread_create(&ignore1, &attr, readerthread(minheap, eventlist, nowtimestamp), 0);
pthread_create(&ignore2, &attr, sequencerthread, 0);
pthread_attr_destroy(&attr);
pthread_exit(0);
return (EXIT_SUCCESS);
}
This line is the problem:
pthread_create(&ignore1, &attr, readerthread(minheap, eventlist, nowtimestamp), 0);
You're calling readerthread on the main thread and passing its result to pthread_create. Since readerthread never returns, you never even get to the first call to pthread_create, let alone the second one.
You need to call it like this instead:
pthread_create(&ignore1, &attr, readerthread, &readerthread_args);
where readerthread_args is a struct encapsulating the arguments to pass to readerthread. You'll also need to change readerthread to take a single void * argument, cast it to the type of readerthread_args, and unpack the args.
You should have got a whole bunch of warnings from your compiler. Did you remember to turn them on?
Related
// The thread of the periodic task is running in an infinite loop. I have included a flag and sleep(), so that it executes only for a certain time and then goes to sleep. But, after the modification, I am not getting the output "executing thread" at all. Please suggest, how to modify the use of the sleep function so that I get the output "executing thread" for the time and then it goes to sleep.//
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>
#include <unistd.h>
int exitflag=0;
struct task_spec_struct
{
char task_type;
int period,r_min,r_max;
}s1;
int gen_rand(int a, int b)
{
srand(time(NULL));
int x = a+(rand()%(b-a));
return x;
}
//task body to utilize CPU to perform computations
void* periodic_task(void* arg)
{
struct task_spec_struct *arg_struct = (struct task_spec_struct*) arg;
int rand_num = gen_rand(arg_struct->r_min, arg_struct->r_max);
while(1)
{
int i, j=0;
for(i=0; i<rand_num; i++)
{
j=j+i;
}
if (exitflag==1)
{
pthread_exit(0);
}
usleep((arg_struct->period)*1000);
printf("Executing thread1");
}
//pthread_exit(0);
}
int main(int argc, char **argv)
{
int num_args = argc-1;
// Creating pthread for periodic task ( runs Thread function to run periodically)
// printf("\nGive task with specifications:");
s1.task_type= 'P';
s1.period= 300;
s1.r_min= 400;
s1.r_max= 500;
pthread_t tid;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&tid, &attr, periodic_task, &s1);
int ret=sleep(3);
if (ret==0)
{
exitflag=1;
}
pthread_join(&tid, NULL);
}
printf does not flush by default unless you end the string with a newline character. See Why does printf not flush after the call unless a newline is in the format string?.
You are not seeing the output because the buffer is not being flushed. Either add a new line character, or call fflush on stdout.
Now this is just a little test, and part of a school assignment. In my code printf is not printing at least to me being able to see it. Is this a result of the thread not functioning? The print line works outside of the thread. Thank you for any help.
I am new to threading in c.
#include<stdio.h>
#include<pthread.h>
#include<string.h>
#include<stdlib.h>
void *threadServer(void *arg)
{
printf("This is the file Name: %s\n", arg);
pthread_exit(0);
}
int main(int argc, char* argv[]){
int i=1;
while(argv[i]!=NULL){
pthread_t thread;
pthread_create(&thread, NULL, threadServer,argv[i]);
i++;
}
In your code, the parent thread of execution that created another thread finishes execution without waiting for its child threads to finish. And threads, unlike processes, once the parent thread terminates, all its child threads of execution terminate as well.
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
void *threadServer(void *arg)
{
printf("This is the file Name: %s\n", (char*)arg);
pthread_exit(0);
}
int main(int argc, char* argv[]){
int i=1;
while(argv[i]!=NULL){
pthread_t thread;
pthread_create(&thread, NULL, threadServer, argv[i]);
i++;
pthread_join(thread, NULL);
}
}
Doing this will allow the thread created to run, until it finishes execution. The pthread_join will wait for the thread to complete its execution and then move ahead.
EDIT
As people did mention in the comments, it is probably worthless trying to spawn a single thread and joining it immediately, making it no better than a single thread of execution. Hence, for the sake of experimentation, the code can be modified as follows:
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
void *threadServer(void *arg)
{
printf("This is the file Name: %s\n", (char*)arg);
}
int main(int argc, char* argv[]){
int i = 1;
pthread_t thread[argc - 1];
while(i < argc)
{
pthread_create(&thread[i-1], NULL, threadServer, argv[i]);
i++;
}
for (i = 0; i < argc - 1; ++i)
{
pthread_join(thread[i], NULL);
}
}
I've spent quite a few hours on trying to figure this one out and I'm completly stuck. The program is supposed to start 6 threads. Where some threads start where others end. Right now, I'm trying to get one single thread (thread 0) to execute. The caps lock commenting shows where I have added code and done my mistakes. My main struggle here is dealing with the pointers. Could anyone give me any pointers (ha..ha.. :c )?
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#define SHARED 1
sem_t sem[6];
struct threadargs
{
int id; /* thread number */
int sec; /* how many sec to sleep */
int signal[6]; /* which threads to signal when done */
};
void *tfunc(void *arg)
{
int i;
struct threadargs *targs=arg;
sem_wait(sem); //WAIT FOR OWN SEMAPHORE
printf("Thread %d is running\n", targs->id);
sleep(targs->sec);
printf("Thread %d is completed and may wake others..\n", targs->id);
for(i=0; i<6; i++) //ITERATE OVER signal_ARRAY &
{ //WAKE THREAD NUMBER i IF
if(targs->signal[i] == 1) //signal[i] IS 1
pthread_cond_signal(&sem[i]);
}
}
int main(void)
{
int i, j;
struct threadargs *targs[6];
pthread_t tid[6];
for(i=0; i<6; i++)
{
targs[i] = (struct threadargs*) malloc(sizeof(struct threadargs));
for(j=0; j<6; j++)
{ targs[i]->signal[j]=0; }
}
targs[0]->id=1;
targs[0]->sec=1;
targs[0]->signal[1]=1;
targs[0]->signal[4]=1;
sem[0] = 0; //INITIALIZE THREAD'S SEMAPHORE TO 0 or 1
pthread_create(targs[0], NULL, tfunc, NULL) // START THREAD
for(i=0; i<6; i++)
pthread_join(tid[i], NULL);
return 0;
}
Alright. First things first, I do recommend taking a second look at your coding style. It is of course highly subjective and I won't say yours is bad, but it took me a while to figure it out (if you really want to know, I recommend the Linux coding style for C/C++ code).
Lets get on with your problem. As far as I can see, the main issue seems that you're basically comparing pointers to apples with pointers to banana's (in other words, you're using the wrong pointer type in the wrong place).
To make sure that calls to functions and the like are correct, make sure to look up the API documentation for functions that are new to you (examples: pthread_create, sem_init, sem_wait, sem_post, pthread_cond_signal).
As you can see, pthread_cond_signal doesn't take a sem_t* as argument, and therefore you can't pass one to it and expect it to work. Below you'll find an example program showing how semaphores are used.
First, a new thread is created which will be put in waiting state instantly. As soon as the main tread finished counting from 0 to 150, it will post ('unlock') the semaphore and allowing the second thread to finish its execution.
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
static sem_t sem_thread_one;
static pthread_t thread_one_data;
static int x;
static void *tfunc(void *arg)
{
sem_wait(&sem_thread_one);
printf("Thread 1 is running. The value of x is %i\n", x);
return NULL;
}
int main(int argc, char **argv)
{
sem_init(&sem_thread_one, 0 /* don't share between processes */, 0);
if(pthread_create(&thread_one_data, NULL, &tfunc, NULL)) {
fprintf(stderr, "Could not create thread, exiting!\n");
return -EXIT_FAILURE;
}
while(x < 150) {
x++;
}
sem_post(&sem_thread_one);
if(pthread_join(thread_one_data, NULL)) {
fprintf(stderr, "Could not join threads, exiting!\n");
return -EXIT_FAILURE;
}
sem_destroy(&sem_thread_one);
printf("Program ran succesfully!\n");
return -EXIT_SUCCESS;
}
Save in a file sem.c and compile & link using:
gcc -Wall -Os -pthread -o sem_test sem.c
Now a second example, but now using pthread_cond_t. The functionality of the program is somewhat similar, it waits for a counter to reach a certain number.
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
static pthread_t thread_one_data, thread_two_data;
static volatile int x, y, idx = 10;
static int count = 1;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t condition = PTHREAD_COND_INITIALIZER;
static void *cond_test_wait(void *arg)
{
pthread_mutex_lock(&mutex);
while(count < 10) {
printf("Waiting for `count < 10' to become true\n");
pthread_cond_wait(&condition, &mutex);
}
pthread_mutex_unlock(&mutex);
printf("Test wait thread finished. Value of count: %i\n", count);
return NULL;
}
static void *cond_test_signal(void *arg)
{
while(count < 10) {
pthread_mutex_lock(&mutex);
pthread_cond_signal(&condition);
/* do more intelligent things here */
count++;
pthread_mutex_unlock(&mutex);
}
printf("Test signal thread finished\n");
return NULL;
}
int main(int argc, char **argv)
{
if(pthread_create(&thread_one_data, NULL, &cond_test_wait, NULL)) {
fprintf(stderr, "Could not create thread, exiting!\n");
return -EXIT_FAILURE;
}
if(pthread_create(&thread_two_data, NULL, &cond_test_signal, NULL)) {
fprintf(stderr, "Could not create thread, exiting!\n");
return -EXIT_FAILURE;
}
pthread_join(thread_one_data, NULL);
pthread_join(thread_two_data, NULL);
pthread_cond_destroy(&condition);
pthread_mutex_destroy(&mutex);
printf("Program ran succesfully!\n");
return -EXIT_SUCCESS;
}
Save in a file cond.c and compile & link using:
gcc -o cond -pthread -Os -Wall cond.c
Do note how neat condition work in this example. You can use them to wait until any expression (= condition) becomes true. After the condition becomes true normal execution continue's.
If you need any more help, don't hesitate to ask in the comments. Good luck combining the above examples to fix up your program.
I am learning to use semaphores and below is a small scenario which I've tried to implement. Its behaving weird in a way. After sem_wait() gets unblocked first time, its not getting blocked again and keeps on looping, not getting why. Is this the right way or right scenario to use semaphore?
EDIT: I just realized that if I uncomment the sleep after sem_post, it works fine. .Reason being it was repeatedly doing sem_post() before thread could do coin=0 I believe. But is it right to use sleep this way with semaphores. I believe this would be considered a bad practice?
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <semaphore.h>
#define MAX_MSG_LEN 256
sem_t sem1;
sem_t sem2;
int coin=0;
void *thrdFun1(void *arg);
void *thrdFun2(void *arg);
void toggleCase(char *buf, int cnt);
int main()
{
pthread_t thrd1;
char argmsg1[] = "Thread1: Waiting to deliver\n";
int thNum;
int res;
res = sem_init(&sem1, 0,0);
// res = sem_init(&sem2, 0,0);
res = pthread_create(&thrd1, NULL, thrdFun1, argmsg1);
while(1)
{
if (coin==0)
{
printf("no coin: please enter coin\n");
scanf("%d",&coin);
}
else
{
sem_post(&sem1);
// sleep(1);
}
}
return 0;
}
void *thrdFun1(void *arg)
{
while(1)
{
printf("I'm %s\n",(char *)arg);
sem_wait(&sem1);
printf("Delivered...\n");
coin=0;
sleep(1);
}
}
Semaphores are used to control Critical-Section Access. In this case, critical section would be the output shell. The thread may or may not start promptly when the pthread_create() is called. Also, sem_wait() will decrease the value of sem1 with each call. Thus, when you include sleep(1) in the thrdFun1 function, there may be undefined behaviour :)
You need to remove sleep(1); from function thrdFun1. After this there will not be any need of sleep(1) in main.
You realized it right, it is repeatedly doing sem_post() before thread could do coin=0 when removing all sleeps.
To solve this you could use second semaphore (you already tried it seems) like below,
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <semaphore.h>
#define MAX_MSG_LEN 256
sem_t sem1;
sem_t sem2;
int coin=0;
void *thrdFun1(void *arg);
void *thrdFun2(void *arg);
void toggleCase(char *buf, int cnt);
int main()
{
pthread_t thrd1;
char argmsg1[] = "Thread1: Waiting to deliver\n";
int thNum;
int res;
res = sem_init(&sem1, 0,0);
res = sem_init(&sem2, 0,0);
res = pthread_create(&thrd1, NULL, thrdFun1, argmsg1);
while(1)
{
if (coin==0)
{
printf("no coin: please enter coin\n");
scanf("%d",&coin);
}
else
{
sem_post(&sem1); // Coin is spun
sem_wait(&sem2); // Wait till it is caught
}
}
return 0;
}
void *thrdFun1(void *arg)
{
while(1)
{
printf("I'm %s\n",(char *)arg);
sem_wait(&sem1); // Wait to spin the coin
coin=0;
sem_post(&sem2); // inform as caught
printf("Delivered...\n");
}
}
there is a chance that "Thread1: Waiting to deliver" this string can get printed many times.
What you are trying to achieve is looks like producer-consumer problem.
You required two semaphore to achive this.
main function:
while(1)
{
if (coin==0)
{
printf("no coin: please enter coin\n");
scanf("%d",&coin);
}
else
{
sem_post(&sem1);
sem_wait(&sem2)
}
}
in thread function
while(1)
{
printf("I'm %s\n",(char *)arg);
sem_wait(&sem1);
printf("Delivered...\n");
coin=0;
sem_post(&sem2)
}
I'm trying to use a mutex to make a thread wait for user input from the parent thread. The current problem I'm facing is that the child doesn't wait, even though I have a mutex to lock and unlock, then I also join it in the parent thread. Also, I am currently unsure if my struct is being used correctly? Is the main() and *chthread() using the same instance of "lock"? I understand that when I get the user input BEFORE the thread creation that it works, however requirements of this exercise states it is meant to pass information after the thread is created.
#define _GNU_SOURCE
#include <stdio.h>
#include <pthread.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <readline/readline.h>
#include <readline/history.h>
# define BUFFER_SIZE 256
void *chthread(void *arg);
struct {
pthread_t pth;
pthread_mutex_t lock;
int ret;
void* ex;
} muinfo;
int main(int argc, char *argv[])
{
//struct mutex args;
char line[BUFFER_SIZE];
char *temp = NULL;
pthread_mutex_init(&muinfo.lock, NULL);
if((pthread_create(&muinfo.pth, NULL, chthread, line)) != 0) {
perror("Problem creating thread");
}
using_history();
temp = readline("enter a string: ");
strcpy(line, temp);
if((pthread_join(muinfo.pth, &muinfo.ex)) !=0) {
perror("Thread join error");
}
free(temp);
pthread_mutex_destroy(&muinfo.lock);
pthread_exit(NULL);
}
void *chthread(void *arg)
{
//struct mutex args;
pthread_mutex_lock(&muinfo.lock);
char *line = (char*)arg;
printf("testing %s\n", line);
pthread_mutex_unlock(&muinfo.lock);
pthread_exit(&muinfo.ret);
//return NULL;
}
As for your main problem, you need to lock mutex at main first(likely after init it),
and unlock it after getting input from user,
so the child thread will wait until main unlock.
pthread_mutex_init(&muinfo.lock, NULL);
pthread_mutex_lock(&muinfo.lock);
if((pthread_create(&muinfo.pth, NULL, chthread, line)) != 0) {
perror("Problem creating thread");
}
using_history();
temp = readline("enter a string: ");
strcpy(line, temp);
pthread_mutex_unlock(&muinfo.lock);
I remove using_history() and use delayed strcpy fixed string instead readline as test,
and it work fine for me.