#include <stdio.h>
#include <sys/wait.h>
#include <pthread.h>
void* runfunc(void* arguments){
printf("in run thread\n");
return NULL;
}
int main(void)
{
pthread_t pthread_id;
pthread_create(&pthread_id, NULL, runfunc, NULL);
printf("after pthread creation\n");
return 0;
}
$ gcc -pthread intro.c
$ ./a.out
after pthread creation
in run thread
in run thread
$ ./a.out
after pthread creation
$
There are 4 types of outputs for this program on linux.
"after pthread creation" -> this output can be easily understood as before thread execution process completes and exits and deletes all threads.
"after pthread creation
in " -> this output can also be understood as while process was exiting thread executed a little bit to print in
"in running thread
after pthread creation" -> this output can also be easily understood
"after pthread creation
in running thread
in running thread" -> now i don't get why am i getting "in running thread" 2 times instead of once.
Linux implementation of threads is considered.
Related
Can please some one explain the output of the code below!
I was working with threads in C language, and caught my eye that sometimes the output of the programs is not totally one of my prediction.
So I tried to write this code to understand more..
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
void * threadfun(void *arg){
printf("Hello from thread id %ld\n",*(pthread_t*)arg);
return NULL;
}
int main (int argc, char *argv[]){
pthread_t tid;
void * (*fp)(void*) = &threadfun;
printf("The Main program. pid = %d.\n",getpid());
pthread_create(&tid, NULL,fp,(void*)&tid);
printf("%ld was the thread id.\n",tid);
//pthread_join(tid, NULL);
printf("ENd. \n");
return 0;
}
I comment out the join function on purpose.
The output of this code was sometimes something like this:
gcc (Debian 11.2.0-10) 11.2.0
└─$ gcc s1_LD_thread01.c -o out_s1_thread01 -lpthread
└─$ ./out_s1_thread01
The Main program. pid = 8683.
140305239197248 was the thread id.
ENd.
Hello from thread id 140305239197248
Hello from thread id 140305239197248
I am wondering why the created thread outputting two strings.!
I am looking for a ptrace() call to observe a process until the process exits.
I have this which compiles with gcc / cc on OSX:
#include <sys/types.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <stdio.h>
#include <sys/ptrace.h>
int main(int argc, char *argv[]) {
pid_t pidx = atoi(argv[1]);
printf("pid = %jd\n", (intmax_t) pidx);
ptrace(PT_ATTACHEXC, pidx, 0, 0);
wait(NULL);
}
However, even with a valid/existing pid, this program will still exit immediately. I am trying to only exit this program after pidx dies.
Is this possible somehow?
Ideally I want something that works on both OSX and Linux.
Your problem is probably that the wait call returns immediately, because the traced "inferior" process is suspended, you know, waiting for you to debug it. You're going to need some kind of loop in which you make ptrace requests to inspect the child and then resume execution, and then call wait again to wait for it to suspend on the next breakpoint or whatever. Unfortunately the debugger API is extremely non-portable; you will have to write most of this program twice, once for OSX and once for Linux.
Here is my code:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
pthread_t ntid;void
printids(const char *s) {
printf("%s \n", s);
}
void *
thr_fn(void *arg) {
printids("new thread: ");
return((void *)0);
}
int
main(void) {
pthread_create(&ntid, NULL, thr_fn, NULL);
printids("main thread:");
}
I'm running it on Red Hat Enterprise Linux Workstation release 6.5 .
Here is my compiling command
gcc -ansi -g -std=c99 -Wall -DLINUX -D_GNU_SOURCE threadid.c -o threadid -pthread -lrt -lbsd
Here is the output:
main thread:
new thread:
new thread:
Why "new thread" has been printed twice?
I doubt this may related to buffering mechanism in Linux. But after I added fflush(stdout) and fsync(1) in the end of each function. The output is almost the same.
If you run the program several times. The output differs:
main thread:
new thread:
or
main thread:
new thread:
new thread:
Or
main thread:
Most libc libraries do buffer the output as you mentioned. And at the end of the program (when the main thread exits), they flush all the buffers and exit.
There is a slight possibility that your new thread has flushed the output but before it could update the state of the buffer, the main program exited and the cleanup code flushed the same buffer again. Since these buffers are local to the thread I am sure they won't have concurrency mechanism. But because of this rare case it might get messed up.
You can try
err = pthread_create(&ntid, NULL, thr_fn, NULL);
printids("main thread:");
pthread_join(ntid, NULL);
At the end of the main function and check if the problem is solved.
This will cause your main function to wait till the new thread is finished (including the flushing operation it does).
Double output is possible on glibc-based linux systems due to a nasty bug in glibc: if the FILE lock is already held at the time exit tries to flush, the lock is simply ignored and the buffer access is performed with no synchronization. This would be a great test case to report to glibc to pressure them to fix it, if you can reproduce it reliably.
I have the following code (source):
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 5
void *PrintHello(void *threadid) {
long tid;
tid = (long)threadid;
printf("Hello World! It's me, thread #%ld\n", tid);
pthread_exit(NULL);
}
int main(int argc, char *argv[]) {
pthread_t threads[NUM_THREADS];
int rc;
long t;
for (t=0; t<NUM_THREADS; t++) {
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
// wait for all threads to die
pthread_exit(NULL);
}
I compile with gcc -g main.c -o main -lpthread. I am using GDB for debugging. What I want is to place a breakpoint at the second line of PrintHello, i.e. at tid = (long)threadid, and have the execution stop there (whatever the thread) and let me do stuff like look at the value of variable threadid.
I want to achieve this in Emacs' GDB implementation - which we may assume for the purposes of this question as simply GDB (don't worry that it's run inside Emacs). So far I can place the breakpoint at the desired line, and sometimes the little arrow showing the current line where the program is at does indeed stop at this line:
However when I type into the GDB prompt print threadid I get back No symbol "threadid" in current context. and the arrow jumps immediately to some breakpoint that I set in main():
My guess is that this occurs because the "pausing" of program execution happens for the main thread, which is not the thread running PrintHello. PrintHello is run by thread t - since this is not the thread paused by GDB, it prints the hello world message and exists immediately. By the time I get around to typing print threadid, this thread is already dead and the program is back in main()... hence the effect.
I tried to resolve this by typing something like break <LineNumber> thread <ThreadID> but this is no good since in this program the created threads last for a split second. So I am never actually at a point where info thread shows anything except the main thread. It's simply not humanly possible to "catch" the program at a point where there is the main thread and a newly created thread running PrintHello - since this situation lasts for I guess a few microseconds.
Please help me to achieve this simple debug objective of halting execution of whatever thread is executing PrintHello at the line tid = (long)threadid;.
Solved it, there wasn't much a problem after all. Here are instructions, if anyone has a similar issue:
Compile with gcc -ggdb main.c -o main -lpthread (yes, that's -ggdb and not -g, it appears to make a difference)
Run the debugger with gdb main or, in Emacs, with M-x gdb (and the command gdb -i=mi main)
Hugely important here: Emacs has by default the variable gdb-non-stop-setting set to t, which means it tries to run GDB in non-stop mode. According to docs, this is NOT what I want - I want all-stop mode. Thus, either do a set-variable or put (setq gdb-non-stop-setting nil) in your init file (e.g. ~/.emacs.d/init.el). Only once this is done should you launch M-x gdb from inside Emacs...
(gdb) b 9 to set the breakpoint to line 9
(gdb) r to run the program. Execution will stop when one of the threads reaches line 9, i.e. tid = (long)threadid;. All other threads will also stop! Perfect!
(gdb) c to continue. Execution will stop when another thread reaches line 9. Great!
Continue doing whatever, we have the desired behavior now :)
I am a beginner of multi-threaded programming, and now I know that when a signal was sent while waiting with pthead_cond_wait(), the result depends on the OS.
Can somebody tell me how to know how the call was interrupted, and how to write portable code?
#include <stdio.h>
#include <signal.h>
#include <pthread.h>
void
sigusr1_handler(int sig)
{
printf("signal called\n");
}
int
main()
{
int n;
pthread_mutex_t mut;
pthread_cond_t cond;
struct timespec ts;
signal(SIGUSR1, sigusr1_handler);
pthread_mutex_init(&mut, NULL);
pthread_cond_init(&cond, NULL);
pthread_mutex_lock(&mut);
printf("before cond_wait\n");
n = pthread_cond_wait(&cond, &mut);
printf("after pthread_cond_wait : %d\n", n);
perror("error pthread_cond_wait:");
pthread_mutex_unlock(&mut);
return 0;
}
MacOS X 10.11.4
cc -o condwait condwait.c -lpthread
Linux 2.6.32-642.3.1.el6.x86_64
gcc -o condwait condwait.c -lpthread
Solaris11 5.11 11.2
cc -D_POSIX_C_SOURCE -D_REENTRANT -mt -o condwait condwait.c -lpthread
MacOS X
$ ./condwait &
[1] xxxxx
$ kill -USR1 %1
signal called
after pthread_cond_wait : 0
error pthread_cond_wait:: Unknown error: 260
Solaris
$ ./condwait &
[1] xxxxx
$ kill -USR1 %1
signal called
after pthread_cond_wait : 0
error pthread_cond_wait : Error 0
Linux
$ ./condwait &
[1] xxxxx
$ kill -USR1 %1
signal called
$ jobs
[1]+ Running
When using Solaris native cond_wait(), it returns EINTR as documented.
Is there any idea how to know that pthread_cond_wait() was interrupted?
POSIX specifies that this function will never return EINTR. For portability to legacy OSes you can check for it anyway, it doesn't hurt
More importantly, you should be prepared for spurious wakeups. The function can return zero at any time for any reason wiith the condition not being met. The mutex will be locked. You have to check the condition and, if not met, go back to pthread_cond_wait.
I read the Linux pthread_cond_wait's man manual, it says:
If a signal is delivered to a thread waiting for a condition variable, upon return from the signal handler the thread resumes waiting for the condition variable as if it was not interrupted, or it shall return zero due to spurious wakeup.
I guess other OS's also have manuals to help you figure it out.
Thank you very much for everyone.
Now I know that with using signal to stop long waiting condition do not work.
pthread_cond_wait() resume waiting for the condition as if it was not interrupted, or it returns zero due to spurious wakeup.
Then I want to do that, I will need a second lock like
pthread_mutex_lock(&mut);
while(condition_is_false) {
n = pthread_cond_timedwait();
if (n == ETIMEDOUT) {
pthread_mutex_lock(&mut2);
if (condition2_is_true) {
pthread_mutex_unlock(&mut2);
pthread_mutex_unlock(&mut);
return STOPPED;
}
pthread_mutex_unlock(&mut2);
}
}
pthread_mutex_unlock(&mut);
return 0;
Regards,