what is wrong with following pthread program? - pthreads

I am not able to execute pthreads program in c. Please tell me what is wrong with the following program. I am neither getting any error nor expected output.
void *worker(void * arg)
{
int i;
int *id=(int *)arg;
printf("Thread %d starts\n", *id );
}
void main(int argc, char **argv)
{
int thrd_no,i,*thrd_id,rank=0;
void *exit_status;
pthread_t *threads;
thrd_no=atoi(argv[1]-1);
thrd_id= malloc(sizeof(int)*(thrd_no));
threads=malloc(sizeof(pthread_t)*(thrd_no));
for(i=0;i<thrd_no;i++)
{
rank=i+1;
thrd_id[i]=pthread_create(&threads[i], NULL, worker, &rank);
}
for(i=0;i<thrd_no;i++)
{
pthread_join(threads[i], &exit_status);
}
}

thrd_no = atoi(argv[1] - 1); likely doesn't do what you intended; the way argv is normally passed into a new process and parsed into a C array, argv[1] - 1 is probably pointing at \0 (specifically, the \0 at the end of argv[0]). (More generally, indexing backwards off the start of a string is rarely correct.) The result is that atoi() will return 0 and no threads will be created. What did you actually intend to do there?

You are passing the same address &rank to each thread, so id and *id is the same for all your worker-s.
You should better allocate on the heap the address you pass to each worker routine.
You might also include <stdint.h and use intptr_t, e.g.
void worker (void* p)
{
intptr_t rk = (intptr_t) p;
/// etc
}
and call
intptr_t rank = i + 1;
thrd_id[i]=pthread_create(&threads[i], NULL, worker, (void*)rank);
You should learn to use a debugger and compile with all warnings and debug information, i.e. gcc -Wall -g (and improve your code till it gets no warnings, then use gdb)

code segment rank=i+1;
thrd_id[i]=pthread_create(&threads[i], NULL, worker, &rank);
will produce race condition.

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

CUDA cudaMemcpy: invalid argument

Here is my code:
struct S {
int a, b;
float c, d;
};
class A {
private:
S* d;
S h[3];
public:
A() {
cutilSafeCall(cudaMalloc((void**)&d, sizeof(S)*3));
}
void Init();
};
void A::Init() {
for (int i=0;i<3;i++) {
h[i].a = 0;
h[i].b = 1;
h[i].c = 2;
h[i].d = 3;
}
cutilSafeCall(cudaMemcpy(d, h, 3*sizeof(S), cudaMemcpyHostToDevice));
}
A a;
In fact it is a complex program which contain CUDA and OpenGL. When I debug this program, it fails when running at cudaMemcpy with the error information
cudaSafeCall() Runtime API error 11: invalid argument.
Actually, this program is transformed from another one that can run correctly. But in that one, I used two variables S* d and S h[3] in the main function instead of in the class. What is more weird is that I implement this class A in a small program, it works fine.
And I've updated my driver, error still exists.
Could anyone give me a hint on why this happen and how to solve it. Thanks.
Because the memory operations in CUDA are blocking, they make a synchronization point. So other errors, if not checked with cudaThreadSynchonize, will seem like errors on the memory calls.
So if an error is received on a memory operation, try to place a cudaThreadSynchronize before it and check the result.
Be sure that the first malloc statement is being executed. If it is a problem about initialization of CUDA, like #Harrism indicate, then it would fail in this statement?? Try to place printf statements, and see proper initializations are performed. I think generally invalid argument errors are generated because of using uninitalized memory areas.
Write a printf to your constructor showing the address of the cudaMalloc'ed memory area
A()
{
d = NULL;
cutilSafeCall(cudaMalloc((void**)&d, sizeof(S)*3));
printf("D: %p\n", d);
}
Try to make a memory copy for an area that is locally allocated, namely move the cudaMalloc to above of cudaMemcopy (just for testing).
void A::Init()
{
for (int i=0;i<3;i++)
{
h[i].a = 0;
h[i].b = 1;
h[i].c = 2;
h[i].d = 3;
}
cutilSafeCall(cudaMalloc((void**)&d, sizeof(S)*3)); // here!..
cutilSafeCall(cudaMemcpy(d, h, 3*sizeof(S), cudaMemcpyHostToDevice));
}
Good luck.

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;

Modifying PC in jmp_buf to go to another function

For a user-lever thread library, I need to figure out jumping to a function by modifying PC value stored in jmp_buf.
This is what I have written:
jmp_buf env;
void print (void) {
printf("\nHello World!");
}
static int ptr_mangle(int p) {
unsigned int ret;
asm(" movl %1, %%eax;\n"
" xorl %%gs:0x18, %%eax;"
" roll $0x9, %%eax;"
" movl %%eax, %0;"
: "=r"(ret)
: "r"(p)
: "%eax"
);
return ret;
}
int main() {
int i = setjmp(env);
env[0].__jmpbuf[5] = ptr_mangle(print);
longjmp(env, 2);
return 0;
}
I am trying to modify PC in jmp_buf by setting it to the address of the function I am trying to jump to.
I am getting a segmentation fault.
I am unable to figure out what exactly needs to be done. Do I need to modify SP as well?
Any help would be very much appreciated.
What are you trying to do? Are you not checking for the return value of setjmp? I don't think you are doing this correctly. Have a look at the sample code below to see what would be the output be:
#include <stdio.h>
#include <setjmp.h>
#include <stdlib.h>
void subroutine(jmp_buf);
int main(void)
{
int value;
jmp_buf jumper;
value = setjmp(jumper);
if (value != 0)
{
printf("Longjmp with value %d\n", value);
exit(value);
}
printf("About to call subroutine ... \n");
subroutine(jumper);
return 0;
}
void subroutine(jmp_buf jumper)
{
longjmp(jumper,1);
}
The output would be:
About to call subroutine...
Longjmp with a value of 1.
Which begs the question - why are you trying to modify the IP? It sounds like you overwrote something or the code 'jumped' off into the woods and trampled something and came back with a hard landing i.e. segfault.
The variable env is specifically a struct, do not use an array subscript as you have done. I suspect that is why you got a segfault...
Hope this helps,
Best regards,
Tom.

Resources