#include <stdio.h>
#include "mythreads.h"
#include <stdlib.h>
#include <pthread.h>
void *
mythread(void *arg) {
printf("%s\n", (char *) arg);
return NULL;
}
int
main(int argc, char *argv[])
{
if (argc != 1) {
fprintf(stderr, "usage: main\n");
exit(1);
}
pthread_t p1, p2;
printf("main: begin\n");
Pthread_create(&p1, NULL, mythread, "A");
Pthread_create(&p2, NULL, mythread, "B");
// join waits for the threads to finish
//Pthread_join(p1, NULL);
//Pthread_join(p2, NULL);
printf("main: end\n");
return 0;
}
This is a code from Remzi Chapter 27. Playing around, I'm curious to know why sometimes on run, I get A printed twice. I know why this is happening, because I haven't included the join statement. Why should skipping join cause this?
My output:
shubham#HP:~/OS/Code-Threads-Intro$ ./a.out
main: begin
A
main: end
B
shubham#HP:~/OS/Code-Threads-Intro$ ./a.out
main: begin
A
main: end
B
shubham#HP:~/OS/Code-Threads-Intro$ ./a.out
main: begin
main: end
A
shubham#HP:~/OS/Code-Threads-Intro$ ./a.out
main: begin
main: end
B
A
A
Removing the call the pthread_join() should not cause "A" to be printed twice. (Barring a bug in the implementation.)
But since your fprintf() calls share the same FILE * structure, they may not be not multithread-safe. How and why they could print "A" twice is dependent upon the implementation details of your system's fprintf() function.
Related
I am recently learning about threads in C, and I have noticed something I consider weird.
Let's take the next code:
#include <stdio.h>
#include <pthread.h>
void *sub_routine(void *p)
{
p = NULL;
printf("This is a sub_routine\n");
return (NULL);
}
int main(int argc, char **argv)
{
void *p;
pthread_t thread;
if (argc < 1)
return (0);
p = argv[1];
pthread_create(&thread, NULL, sub_routine, NULL);
sub_routine(p);
return (0);
}
I use this command line to compile my program:
gcc -Wall -Wextra -Werror -pthread pthreads.c
The expected result is to print This is a sub_routine two times. Well that happens but not 100% of the times. Is there any particular reason for that?
When main returns, it exits the program even if other threads are running. Therefore, it’s possible for the thread you spawned to not get to the printf before the main thread returns, in which case the program ends before you’ll see both messages.
One way to address this is to add a call to pthread_join at the end of main to tell the program to wait for the thread you created to finish running before main returns. That will ensure you always see two printouts.
Add pthread_join(thread, NULL) at the end (just before return) of the main thread to join the thread "sub_routine"
The modified version of your code works properly:
#include <stdio.h>
#include <pthread.h>
void *sub_routine(void *p)
{
p = NULL;
printf("This is a sub_routine\n");
return (NULL);
}
int main(int argc, char **argv)
{
void *p;
pthread_t thread;
if (argc < 1)
return (0);
p = argv[1];
pthread_create(&thread, NULL, sub_routine, NULL);
sub_routine(p);
pthread_join(thread, NULL);
return (0);
}
I wrote this program to practice pthread system calls so I used some printing lines to check the results but they are escaped the output is:
Thread 1 created
Thread 2 created
test3
while I think it should be
thread 1 created
test2
thread 2 created
test3
test1
The order may change but I should have this lines so why it escape this print statements?
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
void *function();
void *function2();
int main(int argc, char *argv[])
{
pthread_t tid;
int rc;
rc = pthread_create(&tid, NULL, function(), NULL);
if(rc > 0){
fprintf(stderr, "Error\n");
exit(1);
}
pthread_join(tid, NULL);
sleep(1);
printf("test1\n");
pthread_exit(NULL);
}
void *function(){
int rc;
pthread_t tid;
printf("Thread 1 created\n");
rc = pthread_create(&tid, NULL, function2(), NULL);
if(rc > 0){
fprintf(stderr, "Error\n");
exit(1);
}
printf("test2\n");
pthread_exit(NULL);
}
void *function2(){
pthread_detach(pthread_self());
printf("Thread 2 created\n");
printf("test3\n");
pthread_exit(NULL);
}
rc = pthread_create(&tid, NULL, function(), NULL);
You're trying to call pthread_create() with the pointer returned by calling function() as the function to run in the new thread (Remember, function arguments get evaluated before the function itself is called). Now, function() doesn't actually return any value, but it calls function2() in its body (while evaluating the arguments for another call to pthread_create()), which also doesn't return any value, but does call pthread_exit() instead. Since there's only one thread at that point because only the main process thread is running (pthread_create() hasn't actually been called yet; the call stack looks like main() -> function() -> function2()), the whole program then exits.
You need to call pthread_create() with pointers to function and function2, not the results of calling them:
rc = pthread_create(&tid, NULL, function, NULL);
etc.
I am learning threads using C and found the following 'Hello World' program. When I am printing the vale of pthread_value() within the thread and outside the thread using pthread_join() the values returned by the two threads are completely different.
/******************************************************************************
* FILE: hello.c
* DESCRIPTION:
* A "hello world" Pthreads program. Demonstrates thread creation and
* termination.
* AUTHOR: Blaise Barney
* LAST REVISED: 08/09/11
******************************************************************************/
#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!, %ld\n", tid, pthread_self());
long a= pthread_self();
//pthread_exit(NULL);
long *p = &a;
return p;
}
int main(int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
void *status;
long t;
FILE* file = fopen("test.txt", "r");
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);
}
}
for(t=0; t<NUM_THREADS;t++){
pthread_join(threads[t], &status);
printf("%ld\n",(long)status);
}
/* Last thing that main() should do */
pthread_exit(NULL);
}
Your PrintHello() function returns the address of a local variable. Trying to use that address after the function exits is undefined and anything can happen, from getting a garbage value to your program crashing. Plus instead of dereferencing that address to get at the value it points to (Assuming it was still valid, which, again, it's not), you cast the address to a long and print out the address itself. I doubt that's what you intended to do. The general approach should be to malloc enough memory in the thread to hold its return value, and returning that address. Then in the joining thread, dereference that returned address to get at the actual returned value, and free that memory when done.
I have a main program (in C) which needs to branch out into lua_thread(the main continues to run).This lua_thread calls a lua_script.lua. this lua_script contains a while loop. a lua variable controls this while loop.Currently this loop runs forever.
lua_script.lua
--this loop runs forever, as the exit value is not set yet
a=0
while(a<=0)
do
print("value of a:", a)
end
My goal is to change this lua variable(a) from main program such that it exits this infinite loop. Once this loop ends, it exits the thread and returns to the main program.
main.c
#include <lua.h>
#include <lauxlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
void *lua_thread()
{
int status, result;
double sum;
lua_State *L;
L = luaL_newstate();
luaL_openlibs(L);
status = luaL_loadfile(L, "lua_script.lua");
if (status)
{
fprintf(stderr, "Couldn't load file: %s\n", lua_tostring(L, -1));
exit(1);
}
result = lua_pcall(L, 0, 0, 0);
if (result) {
fprintf(stderr, "Failed to run script: %s\n", lua_tostring(L, -1));
exit(1);
}
lua_close(L);
return 0;
}
int main(void)
{
pthread_t p1;
pthread_create(&p1,NULL,lua_thread,NULL);
pthread_join(p1,NULL);
return 0;
}
If you run the above code
cc -o xcute main.c -I/usr/include/lua5.2 -llua -lm -ldl -pthread
it will go into an infinite loop. I want to somehow control the lua variable and change it to a=1,from the main program so that it comes out of the infinite loop.
the reason for doing such a test is that it will make sure that before the main program exits, this thread exits first by controlling the lua variable.
Please suggest how to change this lua variable so that it exits the while loop.
Interacting with a running lua state from a different thread is not necessarily safe so modifying the script's global variable may or may not be a useful idea depending on where you are planning to be making that change from the C side.
If you wanted to do this you would simply need to use the lua C api to set the global variable of the appropriate name in the appropriate lua state.
An alternate idea would be to create a should_exit global function which is called at the start or end of every loop and when it returns true causes the lua code to break or return. This function can then check anything it wants to on the C side in whatever thread-appropriate manner is desired.
Why to have this loop in Lua? You may loop in c-thread instead, lua_pcalling some entry-point function (e.g. onEvent()) on each iteration.
If loop has to be in Lua script, for example in case of setup-loop-cleanup scheme, you may run script in coroutine and use coroutine.yield() as loop condition. Thread should lua_resume() with true value or exit depending on your c-side condition. (Or resume with false if Lua-side cleanup after the loop is preferred.)
Anyway, Lua is not thread-safe and cannot be called simultaneously from more than one thread.
Oh, you went hard way in your answer (sure that was a great exercise though). Things could be much simpler:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
static volatile int shouldRun = 1; // 1.
static int
fn_sleep(lua_State *L)
{
lua_Integer n = luaL_checkinteger(L, 1);
sleep(n < 0 ? 0 : n);
return 0;
}
static int
fn_shouldRun(lua_State *L)
{
lua_pushboolean(L, shouldRun);
return 1;
}
static void *
thread_main(void *dummy)
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
lua_register(L, "sleep", fn_sleep); // 2.
lua_register(L, "shouldRun", fn_shouldRun);
if (luaL_dofile(L, "script.lua")) {
fprintf(stderr, "%s\n", lua_tostring(L, -1));
lua_pop(L, 1);
}
lua_close(L); // 3.
return 0;
}
int
main(int argc, char *argv[])
{
pthread_t thread;
pthread_create(&thread, NULL, thread_main, NULL);
sleep(5);
shouldRun = 0; // 1.
pthread_join(thread, NULL);
return 0;
}
script.lua:
print("Hi!")
while shouldRun() do
print("Running!")
sleep(1)
end
print("Bye!")
output:
Hi!
Running!
Running!
Running!
Running!
Running!
Bye!
Few things to note:
Polled exit conditions usually do not need any protection. If shouldRun() was called simultaneously with variable update and missed it, then nothing to worry about – it will return false next time. Anyway, you can't even guess where the script is executing, just [re]set the value and wait for completion.
For a pair of specific functions there is no need to write a require/preload-compatible module. Export them into global namespace instead.
For graceful close on error do not just exit(). lua_close() will garbage-collect all userdata used by script, and their __gc metamethod may do something useful like flushing buffers to disk, etc. You lose all chances with hard exit.
It took me two days to come up with this. Hopefully,it will help someone to save sometime.
main.c
#include <lua.h>
#include <lauxlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <assert.h>
#include <fcntl.h>
#include <semaphore.h>
void *lua_thread(void *arg)
{
int status, result, i;
double sum;
lua_State *L=(lua_State *)arg;
int a=0;
status = luaL_dofile(L, "lua_script.lua");
if (status) {
fprintf(stderr, "Couldn't load file: %s\n", lua_tostring(L, -1));
exit(1);
}
printf("Lua thread exiting\n");
return 0;
}
int main(void)
{
lua_State *L;
L = luaL_newstate();
luaL_openlibs(L);
//Open semaphore which will signal Lua loop to exit
sem_t *lex=sem_open("luaexitsem", O_CREAT, 0600, 0);
//Make sure value of the semaphore is 0 before we start running
//so that sem_post sets it to 1 later
int retval;
for(retval=0;retval==0;) {
retval=sem_trywait(lex);
printf("Dec sem val: %d\n", retval);
}
//Start Lua thread
pthread_t p1;
pthread_create(&p1,NULL,lua_thread,L);
sleep(5);
//Signal Lua script to exit
sem_post(lex);
//Wait for Lua thread to exit
pthread_join(p1,NULL);
//Cleanup
printf("Main exiting\n");
lua_close(L);
sem_close(lex);
return 0;
}
To compile
gcc -o main main.c -I/usr/include/lua5.1 -llua5.1 -lm -ldl -pthread
lua_script.lua
require "lualinuxthread"
a=1
while(not linuxthread.signaltoexit())
do
print("value of a:", a)
a=a+1
end
lualinuxthread.c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include <semaphore.h>
#include <errno.h>
#include <fcntl.h>
static int signaltoexit(lua_State *L) {
sem_t *lex=sem_open("luaexitsem", O_CREAT, 0600, 0);
int exitvalue=0, retval;
if (lex!=SEM_FAILED)
retval=sem_trywait(lex);
if (retval==-1) exitvalue=0; else exitvalue=1;
printf("signaltoexit - exitvalue: %d, retval: %d, %x\n", exitvalue, retval, lex);
lua_pushboolean(L, exitvalue);
sem_close(lex);
return 1;
}
static const luaL_Reg libfuncs[] = {
{"signaltoexit", signaltoexit},
{NULL, NULL}
};
LUALIB_API int luaopen_lualinuxthread (lua_State *L) {
luaL_register(L, "linuxthread", libfuncs);
return 1;
}
to compile:
gcc -O -O2 -fpic -shared lualinuxthread.c -o lualinuxthread.so -lpthread -llua5.1
Thank you
I tried to compile this simple pthreads program with this command
$ gcc -pthread -o pthreads pthreads.c
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
void *myThread(void *arg);
int main()
{
pthread_t mythread;
int ret;
ret = pthread_create( &mythread, NULL, myThread, NULL );
if (ret != 0){
printf( "Can't create pthread: %s", strerror(errno));
exit(-1);
}
return 0;
}
void *myThread(void *arg){
// Thread code goes here..
printf("OK! NOW ON THE THREAD\n");
pthread_exit(NULL);
}
but when trying ./pthreads there is no output presented!!
You need to wait for the thread to finish. Otherwise you risk exiting before the thread starts executing.
...
pthread_create( &mythread, NULL, myThread, NULL );
...
// Wait for the thread to finish.
pthread_join( mythread, NULL);
You didn't wait for your thread to finish. You need to use pthread_join().
You problem comes from the fact that you're main thread is returning from main, and thus calling exit (or _exit). All running thread are killed when the program exit. In this case, the worker thread didn't have the time to execute before it is killed.
You can use pthread_join to wait for the completion of the thread before returning from main.
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
void *myThread(void *arg);
int main()
{
void* thread_return;
pthread_t mythread;
int ret;
ret = pthread_create(&mythread, NULL, myThread, NULL);
if (ret != 0)
{
printf("Can't create pthread: %s\n", strerror(errno));
exit(-1);
}
ret = pthread_join(mythread, &thread_return);
if (ret != 0)
{
printf("Can't join pthread: %s\n", strerror(errno));
exit(-1);
}
return 0;
}
void *myThread(void *arg)
{
printf("OK! NOW ON THE THREAD\n");
pthread_exit(NULL);
}
Sanjit's answer is certainly correct, but for the sake of enlarging your threads toolbox, you might also look at pthread_barrier_wait. When you have a simple program with a lot of threads and main looks like "start all worker threads and wait for them to finish", having main and all the workers simply wait on a barrier can be a nice way to avoid having to store all the worker thread ids and join them in a for loop. Barriers also have a lot of other neat uses that sometimes let you avoid unnecessary complexity from doing the same things with mutexes and condition variables.