For the code below my cpu usage is 97%. I am running c code on Ubuntu.
#include <stdio.h>
#include<pthread.h>
void *s_thread(void *x)
{
printf("I am in first thread\n");
}
void *f_thread(void *x)
{
printf("I am in second thread\n");
}
int main()
{
printf("I am in main\n");
pthread_t fth;
int ret;
ret = pthread_create( &fth,NULL,f_thread,NULL);
ret = pthread_create( &sth,NULL,s_thread,NULL);
while(1);
return 0;
}
This simple code is giving me more cpu usage than running only one thread.
int main()
{
printf("I am in main\n");
pthread_t fth,sth;
int ret;
ret = pthread_create( &fth,NULL,f_thread,NULL);
ret = pthread_create( &sth,NULL,s_thread,NULL);
pthread_join(&fth,NULL);
pthread_join(&sth,NULL);
return 0;
}
while(1) uses more CPU cycles, so use pthread_join and join the process so that main thread waits for child threads to complete.
In linux there are 3 threads :
1 - main thread in which your main() is executing
2 - f_thread
3 - s_thread
The main thread waits on a while(1) loop, which is causing heavy resource usage.
You should not use while(1), instead use pthread_join (http://www.manpagez.com/man/3/pthread_join/) .
With pthread_join, your main thread will sleep until other two threads are finished. Thus there won't be unnecessary resource usage.
Put a sleep command into your loop. For example, the following "sleep" command sleeps for one second:
while(1) {
sleep(1);
}
There are other commands that sleep for less time, such as "usleep" provided by unistd.h, which sleeps for a given number of microseconds:
while(1) {
usleep(1000);
}
Related
I'm new to C and I am trying to learn. I'm trying to implement multithreading in my program, but I'm having problems. The program (and the threads) should be going on running in a infinite loop, but actually the programs stops after few seconds. What can I do for having the program running forever? Am I doing something wrong?
#include <stdio.h>
#include <pthread.h>
void *func(void *threadid){
while (1)
{
/* do stuff, but the program terminates after that thread does few cycles */
}
}
int main(){
#define NUM_THREADS 800
pthread_t threads[NUM_THREADS];
int rc, i;
for (i=0; i < NUM_THREADS; i++)
{
rc = pthread_create(&threads[i], NULL, func, (void *)i);
if (rc)
{
printf("Error to create thread, #%d\n", rc);
exit(-1);
}
}
pthread_exit(NULL);
}
As soon as your main thread exits, the program terminates (and so do the threads). If you want your program to never end, you should add a while(1); at the end of you main while loop.
Note that this is not how to do it properly, your threads should have an end, and the master thread should wait for all the threads to be done, before exiting itself.
#include<stdio.h>
#include<signal.h>
#include<pthread.h>
void *print1(void *tid) {
pthread_t *td= tid;//assigning argument to pointer td
pthread_mutex_t lock1=PTHREAD_MUTEX_INITIALIZER;//mutex for synchronization
printf("Running Thread 1\n");
pthread_mutex_lock(&lock1);
printf("1");
printf("2");
printf("3");
printf("4\n");
printf("Coming out of thread1\n");
sleep(2);
pthread_mutex_unlock(&lock1);
pthread_kill(*td,SIGKILL);//or we can use pthread_cancel(*td) killing thread 2
pthread_exit(NULL);
} void *print2(void *arg) {
pthread_mutex_t *lock = arg;//acquiring lock
pthread_mutex_lock(lock);
sleep(5); //sleeps for 5 sec
printf("5");
sleep(5);//sleeps for 5 sec
printf("6");
sleep(5);//sleeps for 5 sec
printf("7");
sleep(5);//sleeps for 5 sec
printf("8\n");
pthread_mutex_unlock(lock);
pthread_exit(NULL);
} int main() {
int s;
pthread_t tid1, tid2;//thread id's
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
printf("creating Thread 1and 2 \n");
sleep(2);
pthread_create(&tid1, NULL, print1,&tid2);//creating thread1
pthread_create(&tid2, NULL, print2,&lock);//creating thread2
sleep(2);
pthread_join(tid1, NULL);//joing to execute thread1
pthread_join(tid2, NULL);
return 0; }
You can kill one or more threads using any method you choose. You are writing the code the threads run, so you can code them to terminate under whatever conditions you like. There's no particular restrictions.
Your code doesn't kill one thread, by the way.
The SIGKILL signal is sent to a process to cause it to terminate immediately (kill). In contrast to SIGTERM and SIGINT, this signal cannot be caught or ignored, and the receiving process cannot perform any clean-up upon receiving this signal. -- Wikipedia
So you told one thread to kill the process, which it did. If you ever feel you need to force a thread to do something, that means you didn't code the thread to do what you wanted it to do in the first place. Instead of trying to kill a thread, code that thread to terminate itself.
I'm implementing the Dining Philosophers problem in c using pthreads.
Each philosopher is represented by a thread.
Each thread needs to be able to execute four different functions.
I'm aware that I can set a thread to execute a function with:
pthread_create(&tid, &atr, func1, NULL);
That's fine, but how do I make the thread execute a different function later on (i.e. func2).
Is there a way to change the function that a thread is executing or am I off the ball entirely?
Thanks
Here's a possibility, demonstrated with a single thread (aside from the main thread).
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
int to_run = 0;
void func0() {
to_run = -1;
while (to_run == -1) putchar('-');
}
void func1() {
to_run = -1;
while (to_run == -1) putchar('*');
}
void *func(void *data) {
while (1) {
switch (to_run) {
case 0:
func0();
break;
case 1:
func1();
break;
case 2:
printf("\nDONE\n");
return NULL;
}
}
}
int main() {
pthread_t tid;
pthread_create(&tid, NULL, func, NULL);
int i;
for (i=0; i<3; i++) {
sleep(1);
to_run = 1;
sleep(1);
to_run = 0;
}
to_run = 2;
pthread_join(tid, NULL);
return 0;
}
You shouldn't need to change the function the thread is running. You should represent each philosopher with a thread (as you said) and each fork with a mutex.
The philosopher threads will simply run a loop of 2 functions think then eat.
think is just a call to sleep.
eat will try to acquire the 2 mutexes that represent his adjacent forks. The philosopher thread will be blocked waiting for the mutexes to unlock. once they unlock then he can lock them himself (pickup_forks) and wait a short period of time (sleep) then unlock them (return_forks).
There is more to it than that, but it should get you past your current problem.
If your program freezes on a mutex lock. Its a deadlock and you may have to revise your algorithm to stop the deadlock.
Here is a code sample of pthread cancellation:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
void *my_routine(void *arg) {
int i;
for (i = 0; i < 10; i++) {
printf("%d\n", i);
}
return NULL;
}
int main(void) {
pthread_t thread;
if (pthread_create(&thread, NULL, my_routine, NULL)) {
fprintf(stderr, "Cannot create pthread\n");
return 1;
}
usleep(20);
pthread_cancel(thread);
pthread_join(thread, NULL);
//fflush(stdout);
sleep(1);
return 0;
}
I compile with:
gcc -pthread -Wall threadtest.c -o threadtest
When executing, sometimes, it prints an additional number after sleep(1).
Sometimes this number is a duplicate:
0
1
2
3
4
4 // printed after sleep(1)
Sometimes not:
0
1
2
3
4
5 // printed after sleep(1)
If I fflush(stdout) before sleep(1), then the additional number is printed immediately.
How can I avoid this weird printf behaviour when cancelling a thread?
Thank you.
You could disable cancellation while doing the printf() and add an explicit cancellation point:
int cancel_state = 0;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel_state);
printf("%d\n", i);
pthread_setcancelstate(cancel_state);
pthread_testcancel();
(error checking left out for the sake of readability)
When using pthread_cancel you should take more care on thread handler.
man page of pthread_cancel explain lot about this.
man pthread_cancel
Check the example program available in the man page
When thread handler start you have to make PTHREAD_CANCEL_DISABLE with the help of pthread_setcancelstate system call, when handler meet the cancellation point set PTHREAD_CANCEL_ENABLE.
In the main check the pthread_cancel success or not with the help of PTHREAD_CANCELED macro.
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
void *my_routine(void *arg) {
int i;
//pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
for (i = 0; i < 10; i++) {
sleep(1);
printf("%d\n", i);
}
//pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
sleep(60);
return NULL;
}
int main(void)
{
pthread_t thread;
if (pthread_create(&thread, NULL, my_routine, NULL)) {
fprintf(stderr, "Cannot create pthread\n");
return 1;
}
usleep(20);
pthread_cancel(thread);
pthread_join(thread, NULL);
//fflush(stdout);
sleep(1);
return 0;
}
Initially compile and run the above program, note the output. It may not display anything and terminate the program because after thread created thread handler will wait 1sec and sleep, in that time parent thread will cancel the thread and finish process.
Then uncomment the two pthread_setcancelstate() from above program, now compile and run the program. It will now display from 1 to 9. Because thread is set as PTHREAD_CANCEL_DISABLE so parent pthread_cancel will not cancel and wait for PTHREAD_CANCEL_ENABLE.When thread handler meet PTHREAD_CANCEL_ENABLE parent thread will cancel the thread.
when you note the output. handler will not stay on sleep(60), because before that parent will cancel the thread.
i have this piece of code:
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <time.h>
int number;
pthread_mutex_t *mutex;
pthread_t *threads;
void *PrintHello(void *threadid)
{
long tid;
tid = (long)threadid;
printf("Hello World! It's me, thread #%ld!\n", tid);
time_t rawtime;
struct tm * time_start;
time ( &rawtime );
time_start = localtime ( &rawtime );
printf ( "The number %ld thread is created at time %s \n",tid, asctime (time_start));
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
int i,rc;
printf("give threads");
scanf("%d",&number);
mutex = calloc( number, sizeof(*mutex));
threads = calloc(number, sizeof(*threads));
for (i = 0; i < number;i++) {
pthread_mutex_init( &mutex[i],NULL);
}
for(i=0; i<number; i++){
printf("In main: creating thread %d\n", i);
rc = pthread_create(&threads[i], NULL, PrintHello, (void *)i);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
return 0;
}
The purpose of this code is to ask the user to give the number of the threads that it is going to create and after the creation of the threads,the thread itself will print 2 messages saying the number of the thread and the time that it was created.
The problem is that inside the main the message "In main: creating thread" is showing up but the message inside the threads sometimes does not.
For example, it would create 3 threads and only 1 thread will show up its message and that thread also will not show up the time that was created. I dont know if there is something wrong with the code.
Root Cause:
Your main() exits before the child threads get an opportunity to complete their task.
Solution:
You need to make sure that the main() waits until all the threads have completed their work.
You need to use:
pthread_join()
to achieve this functionality. Add the following before returning from main():
for(i=0; i<number; i++)
{
pthread_join(threads[i], NULL);
}
Other problems:
You allocate memory dynamically but never deallocate it. Eventhough, the OS reclaims the memory once your program returns. It is a good practice to do so explicitly.
You created a mutex but you neither use it, nor deallocate it. But that seems to be code in progress.
Return from main() is equivalent to calling exit(...), which terminates the whole process. You may use pthread_join() to wait for each non-main thread, like another answer advises, or you may call pthread_exit(NULL) in the end of your main(): it would exit the initial thread, but other threads will continue to run.