Change lua variable from C

I have a main program (in C) that needs to fork into lua_thread (the main one continues to work). This lua_thread calls lua_script.lua. this lua_script contains a while loop. the lua variable controls this while loop. This cycle is currently running 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 (a) variable from the main program so that it exits this endless loop. As soon as this cycle completes, 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

. - lua a = 1, , . , , , lua. , lua, while.

+4
4

lua , script , C.

, lua C api lua.

should_exit, , true, lua break return. , , .

+4

Lua? c-, lua_pcall - - (, onEvent()).

Lua script, , -, script coroutine.yield() . Thread lua_resume() true c-side. ( false, Lua .)

, Lua .

+1

, (, , ). :

#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!")

:

Hi!
Running!
Running!
Running!
Running!
Running!
Bye!

:

  • . shouldRun() , - false . , , script, [re] .
  • / . .
  • exit(). lua_close() userdata, script, __gc - , , .. .
+1

, . , - -.

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;
}

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;
}

:

gcc -O -O2 -fpic -shared lualinuxthread.c -o lualinuxthread.so -lpthread -llua5.1

0

All Articles