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.
Related
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.
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;
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
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;
What is the point of lua_lock and lua_unlock?
The following implies it's important:
LUA_API void lua_gettable (lua_State *L, int idx) {
StkId t;
lua_lock(L);
t = index2adr(L, idx);
api_checkvalidindex(L, t);
luaV_gettable(L, t, L->top - 1, L->top - 1);
lua_unlock(L);
}
LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
StkId t;
TValue key;
lua_lock(L);
t = index2adr(L, idx);
api_checkvalidindex(L, t);
setsvalue(L, &key, luaS_new(L, k));
luaV_gettable(L, t, &key, L->top);
api_incr_top(L);
lua_unlock(L);
}
The following implies it does nothing:
#define lua_lock(L) ((void) 0)
#define lua_unlock(L) ((void) 0)
Please enlighten.
If you port Lua to another platform, you are "allowed" to overwrite lua_lock with your own definition; and this definition should essentially be a mutex, to disallow cross-thread operations on the same Lua objects. Essentially, when implemented, it should act similarly to Python's Global Interpreter Lock (GIL).
It's defined to a no-op in vanilla Lua, because vanilla Lua is 100% ANSI-C and runs in a single thread: there's no need for any locking mechanism to be implemented. However, the developers chose to put the lock statements in there for people who port Lua and implement threading in the interpreter.
Sources:
Proposal: fast lua_lock
Why write lua_unlock before lua_lock?
Mailing list