This program should be a trivial attempt to run two concurrent threads which both need to write on the same screen.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <ncurses.h>
void *function1(void *arg1);
void *function2(void *arg2);
int main(int argc, char *argv[])
{
printf("hello");
initscr();
printw("screen on\n");
pthread_t function1t;
pthread_t function2t;
if( pthread_create( &function1t, NULL, function1, NULL) < 0)
{
printw("could not create thread 1");
return 1;
}
if( pthread_create( &function2t, NULL, function2, NULL) < 0)
{
printw("could not create thread 2");
return 1;
}
endwin();
return 0;
}
void *function1(void *arg1)
{
printw("Thread 1\n");
while(1);
}
void *function2(void *arg2)
{
printw("Thread 2\n");
while(1);
}
But it doesn't even print hello in the beginning. What's wrong? How can a unique screen be handled in such a program, with two threads?
Update: putting a refresh(); after each printw produces the following output
screen on
Thread 1
Thread 2
$
Where $ is the prompt. So, the program prints the string, but it puts (apparently) randomly some unexpected newlines and it ends. It shouldn’t, due to the while(1) instructions in both the threads!
curses/ncurses in the normal configuration does not support threads, and the recommendation for that has always been to run curses in a single thread. Since ncurses 5.7, there has been rudimentary support for threaded applications if the library is configured (compile-time) to use mutexes and additional entrypoints.
Regarding mutexes, almost any tutorial on POSIX threads covers that. Here is an example: POSIX Threads Programming
It is not printing the hello string but it's quickly cleared with the instruction initscr():
The initscr code determines the terminal type and initializes all
curses data structures. initscr also causes the first call to refresh
to clear the screen. If errors occur, initscr writes an appropriate
error message to standard error and exits; otherwise, a pointer is
returned to stdscr.
printw is printing as expected because you are not refreshing. You should use refresh() after each printw:
printw("screen on\n");
refresh();
Related
I am trying to create a c program which has an infinite loop in the main method (multi-threaded application). We are using pthreads and POSIX shared memory between two applications. If I exit one of the programs using the command line (CTL+C), then I want to run a cleanup method to cleanup all allocated memory and removed the POSIX shared memory map.
int main () {
for (;;)
{
}
destroy_shared_object(shm, MEM_MAP_SIZE);
exit(EXIT_SUCCESS);
return 0;
}
Right now this is what I have above, however when I exit the program I don't think it removes the shared memory map and cleans up. Any help would be appreciated!
You may catch CTRL+C with a signal() handler and set a flag variable within the signal handler:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
static volatile sig_atomic_t running = 1;
void sighandler(int signum) {
running = 0;
}
int main() {
signal(SIGINT, sighandler);
while(running) {
sleep(1);
}
printf("Do the cleanup...\n");
return 0;
}
EDIT:
It's probably better to use sigaction() instead:
WARNING: the behavior of signal() varies across UNIX versions,
and has also varied historically across different versions of
Linux. Avoid its use: use sigaction(2) instead. See > Portability
below.
I'm fairly new to threads in C. For this program I need to declare a thread which I pass in a for loop thats meant to print out the printfs from the thread.
I can't seem to get it to print in correct order. Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define NUM_THREADS 16
void *thread(void *thread_id) {
int id = *((int *) thread_id);
printf("Hello from thread %d\n", id);
return NULL;
}
int main() {
pthread_t threads[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; i++) {
int code = pthread_create(&threads[i], NULL, thread, &i);
if (code != 0) {
fprintf(stderr, "pthread_create failed!\n");
return EXIT_FAILURE;
}
}
return EXIT_SUCCESS;
}
//gcc -o main main.c -lpthread
That's the classic example of understanding multi-threading.
The threads are running concurrently, scheduled by OS scheduler.
There is no such thing as "correct order" when we are talking about running in parallel.
Also, there is such thing as buffers flushing for stdout output. Means, when you "printf" something, it is not promised it will happen immediately, but after reaching some buffer limit/timeout.
Also, if you want to do the work in the "correct order", means wait until the first thread finishes it's work before staring next one, consider using "join":
http://man7.org/linux/man-pages/man3/pthread_join.3.html
UPD:
passing pointer to thread_id is also incorrect in this case, as a thread may print id that doesn't belong to him (thanks Kevin)
The following prints
In Main()
Hello World
Hello World
Why does this print Hello World twice? If I use pthread_join() the desired output occurs (only one Hello World preceeded by a In Main().
#include <pthread.h>
void *thread_func(void *arg);
int main(int argc, char **argv)
{
int s;
void *res;
pthread_t t1;
s = pthread_create(&t1, NULL, thread_func, "Hello World\n");
if (s != 0)
printf("Err\n");
printf("In Main()\n");
s = pthread_detach(t1);
if (s != 0)
printf("Err\n");
return 0;
}
void *thread_func(void *arg)
{
char *s = (char *)arg;
printf("%s", s);
pthread_exit(0);
}
I understand pthread_detach tells the library to release all of the resources utilized by the pthread once the thread is terminated... and since I terminate it at the end of thread_func, everything should be okay right?
What am I missing here?
In my opinion you are using a non-thread-safe version of the standard library (prints, fflush...). I have already seen this kind of (apparently) non-logical behavior on a old unix-like real time system. There were two different versions of std library, one for single-threaded mode and one for multithreaded. Of course, the default was single threaded...
In general, accesses to file pointers and similar things should be serialized with mutexes. In your program there are two thread terminations, each may want to call implicitly an fflush, but since the underlying buffers are not meant to be accessed concurrently, it may happen that both flushes write the same data to the output file descriptor.
How can I implement signal Handling for Ctrl-C and Ctrl-D in C....So If Ctrl-C is pressed then the program will ignore and try to get the input from the user again...If Ctrl-D is pressed then the program will terminate...
My program follows:
int main(){
char msg[400];
while(1){
printf("Enter: ");
fgets(msg,400,stdin);
printf("%s\n",msg);
}
}
Thanks,
Dave
When dealing with POSIX signals, you have two means at your disposal. First, the easy (but discouraged) way, signal(). Second, the more elegant, current but complex way, sigaction(). Please use sigaction() unless you find that it isn't available on some platform that you need to work on.
This chapter of the glibc manual explains differences between the two and gives good example code on how to use both. It also lists the signals that can be handled, recommends how they should be handled and goes more in depth on how to tell how any given signal is (or is not) currently being handled. That's way more code than I'd want to paste into an answer here, hence the links.
It really is worth the hour or two it would take you to read the links and work through the examples. Signal handling (especially in programs that daemonize) is extremely important. A good program should handle all fatal signals that can be handled (i.e. SIGHUP) and explicitly ignore signals that it might not be using (i.e. SIGUSR1 / SIGUSR2).
It also won't hurt to study the difference between normal and real time signals, at least up to the understanding of how the kernel merges the prior and not the latter.
Once you work through it, you'll probably feel inclined to write up an easy to modify set of functions to handle your signals and re-use that code over and over again.
Sorry for not giving a quick and dirty code snippet to show you how to solve your immediate need, but this isn't a quick and dirty topic :)
Firstly, Ctrl+D is an EOF indicator which you cannot trap, when a program is waiting for input, hitting Ctrl+D signifies end of file and to expect no more input. On the other hand, using Ctrl+C to terminate a program - that is SIGINT, which can be trapped by doing this:
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <stdarg.h>
static void signal_handler(int);
static void cleanup(void);
void init_signals(void);
void panic(const char *, ...);
struct sigaction sigact;
char *progname;
int main(int argc, char **argv){
char *s;
progname = *(argv);
atexit(cleanup);
init_signals();
// do the work
exit(0);
}
void init_signals(void){
sigact.sa_handler = signal_handler;
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = 0;
sigaction(SIGINT, &sigact, (struct sigaction *)NULL);
}
static void signal_handler(int sig){
if (sig == SIGINT) panic("Caught signal for Ctrl+C\n");
}
void panic(const char *fmt, ...){
char buf[50];
va_list argptr;
va_start(argptr, fmt);
vsprintf(buf, fmt, argptr);
va_end(argptr);
fprintf(stderr, buf);
exit(-1);
}
void cleanup(void){
sigemptyset(&sigact.sa_mask);
/* Do any cleaning up chores here */
}
In your example it seems you don't need CTRL-C handlind at all. A "signal(SIGINT,SIG_IGN)" seems enough for you, unless your application must handle a SIGINT coming from some other source.
CTRL-D doesn't usually generates signals, it simply communicates the EOF condition.
You can in general control the behavior of your terminal (we are talking about console input, it isn't?) by using the termios library (also here). You can enable, redefine or disable the "interrupt" character (CTRL-C), the EOF one and many other ones (XON, XOFF, modem control...)
Regards
This is a program for handling signal when pressed Ctrl+c
The syntax for signal function is : signal(signal name, function name);
#include<stdio.h>
#include<signal.h> // for handling signal
void signal_handler()
{
printf("Signal Handled here\n");
}
main()
{
printf("In main function..\n");
// SIGINT is signal name create when Ctrl+c will pressed
signal(SIGINT,signal_handler);
sleep(15);
printf("In main after called from signal_handle \n");
}
#include<signal.h>
#include<unistd.h>
#include<stdio.h>
void signal_catch()
{
printf("hi,Your signal catched Here");
}
int main()
{
signal(SIGINT,signal_catch);
//press ctrl+c
sleep(10);
return 0;
}//end main
//if you want to simply ignore ctrl+c interrupt use following code in main
int main()
{
signal(SIGINT,SIG_IGN);
sleep(100);
return 0;
}//end main
//this program wont accept ctrl+c interrupt for 100 seconds.
I'm practicing C programming for Linux for an exam.
I don't know how to exit the program when user press Ctrl + a ( not Ctrl+c )
For example, looping something until user press Ctrl+a
Could anyone tell me how to check Ctrl+a input?
Notes: I'm using 'gcc' and run output with './a.out'
Thanks in advance for everyone!
Turbo C and other implementations of C for Windows had a function call getch() which would read single characters from the keyboard; those would have done what you want.
In POSIX environments, such as are implemented by gcc-compiled programs under Unix/Linux, that functionality isn't directly there.
There's a library called curses which allows C programs to do full-screen output processing, and there is also getch() functionality in curses. This may end up being the simplest answer to your problem. You'll need to read the documentation on curses and link the header files and library into your program.
There is special support for Ctrl-C, which is translated into a signal by the system. If you want your program to stop as soon as another specific key combination is used, it will be much harder.
you will need to check the standard input of your program, and you will need to set the standard input so the inputs are not buffered (otherwise you won't see any input until it is validated by the user pressing "return"). The latter part would be done with a ioctl() call and would not be portable;
you will need either threads or polling, none of which is very palatable in C.
There are more interesting things to practice in C than these.
catching ctrl-c event
This post answers your question
did you looking for something like this ???
this program won't be stopped since you hit ctrl+A and Enter.
#include <stdio.h>
int main() {
char a;
while( a!=1 ) //Ascii code for ctrl + A == 1
{
a=getchar();
printf("still looping ...\n");
}
printf( "HA! You pressed CTRL+A\n" );
return 0;
}
But if you wanna terminate your program just after pressing ctrl+A (without hitting enter after that), here you are:
#include <stdio.h>
#include <ncurses.h>
int main() {
char a;
initscr();
raw();
while( a!=1 )
a=getch();
endwin();
return 0;
}
for compiling second code using GCC, try this command:
gcc -o program.o -lncurses program.cpp
This will do what you want:
stty intr ^a
./a.out
For extra credit, do the equivalent of "stty intr ^a" using the appropriate library function, e.g. "man termios".
Someone posted first with following code which works for me but I don't know why he deleted his answer.
Original Link : http://www.c.happycodings.com/Gnu-Linux/code18.html
#include <stdio.h>
#include <unistd.h> /* sleep(1) */
#include <signal.h>
void ex_program(int sig);
int main(void) {
(void) signal(SIGINT, ex_program);
while(1)
printf("sleeping .. ZZZzzzz ....\n"), sleep(1);
return 0;
}
void ex_program(int sig) {
printf("Wake up call ... !!! - Catched signal: %d ... !!\n", sig);
(void) signal(SIGINT, SIG_DFL);
}
This is how to set CTRL-A as interrupt to break the process. Notice too that CTRL-C doesn't break it after tcsetattr is called.
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
int main(int argc, char* argv[]) {
struct termios termios;
if ( tcgetattr(0, &termios) != -1 ) {
termios.c_cc[VINTR] = '\x01'; /* CTRL-A */
if ( tcsetattr(0, 0, &termios) != -1 ) {
printf("Ready. Press CTRL-A to break this program\n");
while ( 1 ) {
printf("*\n");
sleep(1);
}
}
}
}