The goal of my assignment is to create a loop to spawn 5 threads with integer arguments 0 through 4. I have 3 files: thread_demo.c that contains the main function, worker.c that contains the function to compute square of the argument, and header.h to keep the 2 files together.
thread_demo.c
#include "header.h"
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <readline/readline.h>
#define NUM_THREADS 5
#define PROMPT_SIZE 5
int main(){
pthread_t threads[NUM_THREADS];
pthread_attr_t pthread_attributes;
int *prompt;
scanf("%d", &prompt);
for(int i = 0; i < NUM_THREADS; i++){
pthread_create(&threads[i], &pthread_attributes, &worker, (void *) prompt);
}
}
worker.c
#include "header.h"
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void *worker(void * num){
int *input;
input = (int*) #
// Calculate square
int output = *input * *input;
printf("The square of %d", *input);
printf(" is %d.\n", output);
pthread_exit(NULL);
}
I have no compile errors, but the number of threads my code spawns is inconsistent. The pictures shown are my outputs from entering "5" 3 different times in which I have not made changes to the code. I'm not sure what causes this, I know I'm missing something but I don't know what it is.
I also have to make "the main thread wait until all threads have completed", which is confusing to me. When I spawn the 5 threads, how do I know which is the main thread?
I've never wrote code related to processes and threads so I'm completely lost. Any help would be greatly appreciated!
Your program is probably exiting before all your threads are complete. This would explain why you see different outputs on different runs: sometimes your program exits more or less quickly allowing less or more of the work to complete.
You need to keep your program from exiting (returning from main()) until all your thread are finished. To do this, you can use pthread_join for each of the threads. Add after you create all the threads:
for(int i = 0; i < NUM_THREADS; i++) {
pthread_join(threads[i]);
}
ptread_join will block (stop execution at that line) until the thread has terminated.
From the docs:
The pthread_join() function waits for the thread specified by thread
to terminate. If that thread has already terminated, then
pthread_join() returns immediately. The thread specified by thread
must be joinable.
http://man7.org/linux/man-pages/man3/pthread_join.3.html
Related
I am trying something in C on hp-nonstop(tandem),
As part my task is to wait for sometime.
I try to use the
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main()
{
int i;
for(i=0;i<10;i++)
{
printf("Something");
sleep(5);
printf("Something");
fflush(stdout);
}
}
It's compiling without any problem,
While running it is giving ABENDED: each time different no.
The result calling sleep() from guardian environment is undefined. That might be leading to ABEND that you mentioned. If you want to wait for some time in guardian hp-nonstop environment, you should call DELAY(). It takes centi-seconds as arguments. So if you want to add delay of 5 seconds, you should call it as DELAY (500). You also need to include the header #include<cextdecs(DELAY)>
I have this very simple program to test out named semaphores:
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <sys/ipc.h>
#include <unistd.h>
#include <sys/shm.h>
#include <fcntl.h>
sem_t thing;
void processOne() {
sleep(1);
int l;
sem_getvalue(&thing, &l);
printf("processOneThing: %d\n", l);
}
void processTwo(){
sem_wait(&thing);
printf("done");
}
int main(int argc, char **argv) {
int pidOne, pidTwo;
thing = *sem_open("/testest", O_CREAT|O_EXCL,0777,1);
pidTwo=fork();
if(pidTwo==0){
processTwo();
}
else{
pidOne=fork()
if(pidOne==0){
processOne();
}
else{
}
wait(&pidTwo);
wait(&pidOne);
}
sem_unlink("/testest");
sem_close(&thing);
}
The output is:
doneprocessOneThing: 1
Which means that the second process decremented the semaphore however the value of it in the first child process is still 1...
I have no idea what I am doing wrong and I looked at the named semaphore documentation and could not find much that could help me with this issue.
I'm compiling using:
gcc test.c -pthread
Any and all help would be much appreciated.
First, the code is missing a ; at end of this line:
else{
pidOne=fork() <------ here
if(pidOne==0){
processOne();
}
And it fails to #include<sys/wait.h> for wait() prototype. But correcting these issues I get the same output as you. So what is happening? The issue is with how you created the semaphore:
sem_t thing;
...
thing = *sem_open("/testest", O_CREAT|O_EXCL,0777,1);
The return from sem_open is the address of the created semaphore. But you are dereferencing that address and placing a copy of the contents into your variable thing. That means thing isn't actually the semaphore you created, but just a copy of the struct holding state information. The upshot is that interacting with thing in your code isn't actually interacting with what you intended. (In fact, you might get some indication that something isn't right if you check the return values on sem_wait() and sem_getvalue().)
If you instead make thing a pointer to the semaphore and interact with that, you get the following output:
done
processOneThing: 0
which is I think what you expected to see. You can try the corrected code here:
Runnable corrected code
I am trying to write a program, caller, which traps SIGINT with sigaction, and calls an external program, prog.
I understand how to use sigaction on a simple program, but I don't know how to use it to set signal handlers for other processes (called by execl, for example).
The following is a MWE:
caller.c is this:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
void got_sig(int sig) {
printf("SIGNAL caught: %d\n",sig);
}
int main () {
struct sigaction sa;
(void) sigfillset(&sa.sa_mask);
sa.sa_handler = got_sig;
sa.sa_flags=0;
sigaction(SIGINT,&sa,NULL);
printf("\n");
execl("./prog", "./prog", (char*) NULL);
}
prog.c is this:
#include <stdio.h>
#include <unistd.h>
int main() {
for(int i=0; ; i++) {
sleep(1);
printf("epoch: %d\n",i);
}
}
But when I run caller, I see the output of prog.c, and hitting ^C does stop the prorgam (the signal is not trapped).
I suppose this is related to how execl works (it creates a new process, which does not inherit the parents' signal handlers -- is this right?)
So, how can I accomplish what I am trying to do?
Thank you!
execl("./prog", "./prog", "./prog", (char*) NULL);
Or if it's not working, check out here: https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html
Absolutely strange situation on thread creation , here the test code :
#include <stdint.h> /* C99 types */
#include <stdbool.h> /* bool type */
#include <stdio.h> /* printf, fprintf, snprintf, fopen, fputs */
#include <string.h> /* memset */
#include <signal.h> /* sigaction */
#include <time.h> /* time, clock_gettime, strftime, gmtime */
#include <sys/time.h> /* timeval */
#include <unistd.h> /* getopt, access */
#include <stdlib.h> /* atoi, exit */
#include <errno.h> /* error messages */
#include <math.h> /* modf */
#include <assert.h>
#include <sys/socket.h> /* socket specific definitions */
#include <netinet/in.h> /* INET constants and stuff */
#include <arpa/inet.h> /* IP address conversion stuff */
#include <netdb.h> /* gai_strerror */
#include <pthread.h>
void thread_up(void) {
printf("thread ....\n");
int loop=0;
while(loop<=7)
{
printf("loop...\n");
sleep(10);
loop++;
}
printf("Exit loop\n");
}
int main()
{
pthread_t thrid_up=0;
int i = pthread_create( &thrid_up, NULL, (void * (*)(void *))thread_up, NULL);
if (i != 0) {
printf("ERROR: [main] impossible to create upstream thread\n");
exit(1);
}
while(1)
{
sleep(10);
}
}
that code produce the following output on ps command (after ./test& launching):
30214 root 704 S ./test
30215 root 704 S ./test
30216 root 704 S ./test
Any hint ?
Just a note. man 7 pthreads
LinuxThreads
The notable features of this implementation are the following:
In addition to the main (initial) thread, and the threads that the
program creates using pthread_create(3), the implementation
creates a "manager" thread. This thread handles thread creation
and termination. (Problems can result if this thread is
inadvertently killed.)
Threads do not share process IDs. (In effect, LinuxThreads
threads are implemented as processes which share more information
than usual, but which do not share a common process ID.)
LinuxThreads threads (including the manager thread) are visible as
separate processes using ps(1).
Regardless that this doc is about Glibc your version uClibc may use LinuxThreads as pthread "backend". So technically your code may create three scheduling entities.
But first of all you really must ensure that ps prints threads, not only processes and double check that there is only one launched instance of your program during the probing.
P.S. Also you should check that your uClibc really uses LinuxThreads not NPTL. So IMO the chance to observe three threads exists, but it is very small.
ps shows you the process, not threads.
Probably you only started 3 times your app using ./test &
To test it kill all processes using: killall test
So start again your process and see the output of: ps -A | grep test
It will show you 1 instance of test
Then using: ps -eLf | grep test you'll see threads of test.
EDIT
Related to #Serhio answer, that is probably correct, looking into uClibc source at this link you can find, into libpthread directory, that LinuxThreads are used, so a thread manager is added.
yes... right (#Serhio and #LPs)... my uClibc use the manager i've just checked.
Unfortunately my ps is very poor due to tyny linux embedded enviroment.
So my program is effectively a DPLL SAT solver, therefore inside the program it needs to choose random variables to assign TRUE or FALSE to. If I run my once program it works fine!If if run it again it will choose different variables and still work (this is what I want).
However to produce reliable experiments I need to do repeat runs of my program. This could be done by running the program multiple times separately, but this is tedious and will take too long. I have learnt how to use bash as follows:
#!/bin/bash
for ((i=50; i>0; i--))
do
./Project 90 10 >> outfile.txt
done
However when this is done, every run picks the same 'random' variables in the same order and so produces the same results. How can I make my program run differently each time??
Thanks!!
You need to initialize the random number seed, random numbers are not really random, add this to your main()
#include <time.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
srand(time(NULL)); /* here at the very beginnig of main */
.
.
.
return 0;
}
this will give a different seed every time the program is executed, since time(NULL) will return a different value.
Read this for more information.
Note: as commented by Ingo Leonhardt the effect will be the same, so try this option
#include <stdlib.h>
#include <sys/time.h>
int main(int argc, char **argv)
{
struct timeval tv;
gettimeofday(&tv, NULL);
srand(tv.tv_usec); /* here at the very beginnig of main */
.
.
.
return 0;
}
or, since every process will have a different pid this could also work1
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char **argv)
{
srand((int)getpid()); /* here at the very beginnig of main */
.
.
.
return 0;
}
1This is a POSIX solution, if you want you can research what is your OS equivalent if it doesn't support POSIX.