Use thread local store lua_State - lua

I need to use Lua in IOCP, and use Thread local Storage to store lua_State *. I should use lua_close() destroy the lua_State before the thread destroyed, but the work thread is created by IOCP.
The question is when is the right time to call lua_close?
static DWORD WINAPI work_thread_proc(void* parameter){
lua_State * L = TlsGetValue(tls_lua_key);
if(NULL = L){
L=luaL_newstate();
//DO some initialze for L...
TlsSetValue(tls_lua_key,L);
}
}
//..... other place call
QueueUserWorkItem(&work_thread_proc, req, WT_EXECUTELONGFUNCTION);

you can use it like this.
__declspec(thread) lua_State *tls_LuaState = NULL;
// close lua state on exit thread.
void NTAPI TLS_CloseLuaState(PVOID module, DWORD reason, PVOID reserved)
{
if(NULL != ){
lua_close(tls_LuaState);
}
}
#pragma section(".CRT$XLB",long,read)
__declspec(allocate(".CRT$XLB"))
PIMAGE_TLS_CALLBACK p_thread_callback_base = TLS_CloseLuaState;

Related

passing an ofstream object to a thread function via pthread_create

I want to pass an ofstream object to a thread using pthread_create function.
Let's say I create an object like this in my main(int argc, char *argv[]) function.
ofstream file1(argv[1], fstream::out|fstream::app);
pthread_t tid;
pthread_create(&tid, NULL, function1, (void *)args);
And the function1 is defined as.
void function1(void *input)
{
ofstream file;
file = ??
file << "Hello" << endl;
}
How can I access "file1.txt" created in the main function via the file object?
There are several ways to pass the object. One would be to make it global, then then it's very straightforward for function1() to access it. Or you can pass a pointer to it as the thread's argument. Cast it to void* in the pthread_create() call and cast it back in the thread function.
void* function1(void *input) {
ofstream* file = static_cast<ofstream*>(input);
*file << "Hello" << endl;
return NULL;
}
ofstream file1("./file1.txt", fstream::out|fstream::app);
pthread_t tid;
pthread_create(&tid, NULL, function1, static_cast<void*>(&file1));
Be warned, there is a common bug that this pattern often leads to! The ofstream will be destructed when the scope it was created in ends, which is in the thread that called pthread_create(). If the thread running function1() is still running, it could use the pointer to the now destructed ofstream.
You need to insure that the ofstream remains alive until the other thread is done with it. One way would be to give it static storage duration, either as a static local variable or as a global variable. Another would to allocate it with new and then delete it in the thread that is using it. Or you could insure that the created thread is joined before the ifstream leaves scope.
Using new and delete:
void start(void) {
ofstream* file1 = new ofstream("file1.txt", fstream::app);
pthread_create(&tid, NULL, function1, static_cast<void*>(file1));
file1 = NULL; // function1 owns this now, shouldn't be used here anymore
}
void* function1(void* arg) {
ofstream* file1 = static_cast<ofstream*>(arg);
delete file1;
}
Joining before the ofstream leaves scope:
void start(void) {
{
ofstream file1("file1.txt", fstream::app);
pthread_create(&tid, NULL, function1, static_cast<void*>(file1));
// stuff
pthread_join(tid);
// now it's safe for file1 to be destructed.
}
}
Also note that the thread function should return void*, not void. Also it should be declared as extern "C" so that it will have the correct ABI when the C pthreads library calls it. Notice how in the new/delete example, I set the pointer to NULL after starting the thread. This is because you can not assume it is safe to access the ofstream from more than one thread at a time. By setting it to NULL, only the function1 thread will be able to access it.
Consider also, maybe it makes more sense to pass the name to the thread and have it open the file? This solves the issues around the lifetime of the object vs the lifetime of the thread using it.

Not able to setting thread scope.

I am learning about pthreads,I want to set the scope of a thread so for setting scope I used pthread_attr_setscope() API but when I try to get scope of a thread using pthread_attr_getscope() API it all ways return me 0 regardless what ever scope I set(either PROCESS_SCOPE/SYSTEM_SCOPE). For more information please find code below.
#include <pthread.h>
#include <stdio.h>
#include <unistd.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];
pthread_attr_t attr;
int rc;
long t;
int ret=0;
int mypolicy=-1;
int iscope=-1;
ret = pthread_attr_init (&attr);
pthread_attr_setschedpolicy(&attr,SCHED_RR);
// BOUND behavior - Creating SYSTEM_SCOPE thread
ret = pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
//Unbound behaviour - Creating process scope thread
ret = pthread_attr_setscope(&attr,PTHREAD_SCOPE_PROCESS);
for(t=0; t<NUM_THREADS; t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
printf("Return code from pthread_create() is %d\n", rc);
printf("Return value of getschedule policy = %d \n",pthread_attr_getschedpolicy(&attr, &mypolicy));
printf("policy = %d \n",mypolicy);
printf("Return value of getscope = %d \n",pthread_attr_getscope(&attr,&iscope));
printf("scope = %d \n",iscope);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
_exit(-1);
}
}
pthread_exit(NULL);
}
I don't know why every time I get the same value of 'iscope' regardless what ever scope I set(either PROCESS_SCOPE/SYSTEM_SCOPE).
You don't check for errors in your pthread_attr_setscope calls. Put
if (ret) perror("pthread_attr_setscope");
immediately after both calls, and see what it prints. (It may be that your OS does not support one or other of the scheduling modes.)
You call pthread_attr_setscope twice in a row on the same pthread_attr_t with two different scope constants. This cannot possibly be what you want.
You need to pass the pthread_attr_t as the second argument to pthread_create, instead of the NULL you have there, for the changed setting to have any effect at all.
Once you make that change, the scheduling policy will apply to the just-created thread, but pthread_attr_getscope is being called in the main thread. Move it to PrintHello if you want to know the policy for the just-created thread.
You never used your ret variable, so the gcc compiler complained about that (I used -Wall).
Pick a scope -- you've set it twice, sequentially, as zwol mentioned
However, you don't need to use pthread_attr_getscope in the thread itself; the pthread_attr_getscope function simply reports on what's been set in the attribute.
Use pthread_attr_setinheritsched(&attr,PTHREAD_EXPLICIT_SCHED); - on systems that support multiple contention scopes, this call is needed to get pthread_create to honor the scheduler attribute. Otherwise, the new thread will simply inherit the main thread's scope.
If you're using Linux - Linux only supports PTHREAD_SCOPE_SYSTEM, so trying to set PTHREAD_SCOPE_PROCESS is, essentially, just ignored

Is it safe use for different threads one function?

Is it safe use for different threads one function? Or I must use semaphores here?
static void *func1(void *arg)
{
...
return NULL;
}
int main()
{
...
pthread_create(&thread, &thread_attr, func1, (void *)data);
pthread_create(&thread2, &thread_attr2, func1, (void *)data2);
...
return 0;
}
Thanks!
You can have multiple threads use the same function. You only need to use synchronization (semaphores, mutex, etc) if that function uses data that would be shared between the threads. If all data is in data and data2, then no semaphores would be needed.

How Lua deal with the stack?

I'm trying Lua and want to know how lua_State working
code and result:
state.c
#include <stdio.h>
#include "lua/src/lua.h"
#include "lua/src/lauxlib.h"
static void stackDump(lua_State *L){
int i;
int top = lua_gettop(L);
for(i = 1; i<= top; i++) {
int t = lua_type(L, i);
switch(t){
case LUA_TSTRING:
printf("'%s'", lua_tostring(L, i));
break;
case LUA_TBOOLEAN:
printf(lua_toboolean(L, i) ?"true":"false");
break;
case LUA_TNUMBER:
printf("%g", lua_tonumber(L, i));
break;
default:
printf("%s", lua_typename(L, t));
break;
}
printf(" ");
}
printf("\n");
}
static int divide(struct lua_State *L){
double a = lua_tonumber(L, 1);
double b = lua_tonumber(L, 2);
printf("%p\n", L);
stackDump(L);
int quot = (int)a / (int)b;
int rem = (int)a % (int)b;
lua_pushnumber(L, quot);
lua_pushnumber(L, rem);
stackDump(L);
printf("---end div---\n");
return 2;
}
int main(void){
struct lua_State *L = lua_open();
lua_pushboolean(L, 1);
lua_pushnumber(L, 10);
lua_pushnil(L);
lua_pushstring(L, "hello");
printf("%p\n", L);
stackDump(L);
lua_register(L, "div", divide);
luaL_dofile(L, "div.lua");
stackDump(L);
lua_close(L);
return 0;
}
div.lua
local c = div(20, 10)
0x100c009e0
true 10 nil 'hello'
---start div---
0x100c009e0
20 10
20 10 2 0
---end div---
true 10 nil 'hello'
I see lua_State in divide is the same with the main one, but they have different data in stack, How this be done ?
I know the best way to understand this is to read source code of Lua , maybe you can tell me where to find the right place.
Think of lua_State as containing the Lua stack, as well as indices delimiting the current visible part of the stack. When you invoke a Lua function, it may look like you have a new stack, but really only the indices have changed. That's the simplified version.
lua_State is defined in lstate.h. I've pulled out the relevant parts for you. stack is the beginning of the big Lua stack containing everything. base is the beginning of the stack for the current function. This is what your function sees as "the stack" when it is executing.
struct lua_State {
/* ... */
StkId top; /* first free slot in the stack */
StkId base; /* base of current function */
/* ... */
StkId stack_last; /* last free slot in the stack */
StkId stack; /* stack base */
/* ... */
};
Programming in Lua, 2nd Edition discusses Lua states in chapter 30: Threads and States. You'll find some good information there. For example, lua_State not only represents a Lua state, but also a thread within that state. Furthermore, all threads have their own stack.
It gets different data the same way anything gets different data: code changes the data inside of the object.
struct Object
{
int val;
};
void more_stuff(Object *the_data)
{
//the_data->val has 5 in it now.
}
void do_stuff(Object *the_data)
{
int old_val = the_data->val;
the_data->val = 5;
more_stuff(the_data);
the_data->val = old_val;
}
int main()
{
Object my_data;
my_data.val = 1;
//my_data.val has 1.
do_stuff(&my_data);
//my_data.val still has 1.
}
When Lua calls a registered C function, it gives it a new stack frame.

No cout printing in pthread starting function

i'm new here and noob with pthread programming.
My problem is in a C++ class, that i'm trying to create to encapsulate a thread.
Reading around i'd seen that when i create a pthread, i need to pass a C function to pthread_create that it runs on startup... So, when the pthread runs that function it doesn't cout the message on stdout!
But it's better if you see the code:
(obviously it's copy and pasted from an internet tutorial ^^)
void *runAtStart( void *threadid)
{
long tid;
tid = (long)threadid;
printf("Hello World! It's me, thread #%ld!\n", tid);
pthread_exit(NULL);
}
Thread::Thread() {
pthread_t threads[1];
int rc;
long t;
for(t=0; t<1; t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, runAtStart, (void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
// exit(-1);
}
}
}
in the main i call this as:
int main()
{
Thread *th=new Thread();
return 0;
}
the output generated is:
In main: creating thread 0
i hope that someone has understood!
sorry for my English! :)
Inzirio
Your program runs fine. The problem you're seeing is that your main() function returns before your thread can actually run, and this causes your program to exit.
A simple way to prove this is to add sleep(5); in main(), prior to your return call. A better way is to find a manner to cause main() to wait until all of its threads have completed before it returns. One reasonable manner to do that is to add a destructor to your Thread class that performs a pthread_join, and be sure you actually call the destructor: delete th;

Resources