pthread_create error

G

Gary Wessle

Hi

I am trying to understand how pthread is used, so I make the scenario
below, I could not understand the erros by reading the man
pthread_create.

//**************** code start ****************
#include <iostream>
#include <ctime>
#include <cstdio>
#include <cstdlib>
#include <pthread.h>

using namespace std;

void print_a(){
for ( int i=0; i<10; i++)
cout << "a";
}

void print_b(){
for ( int i=0; i<10; i++)
cout << "b";
}


int main(){

pthread_t thr_a_ID;
pthread_create ( &thr_a_ID, NULL, print_a, NULL );

pthread_t* thr_b_ID;
pthread_create ( &thr_b_ID, NULL, print_b, NULL );
}
//**************** code end ****************

**************** error ****************
main.cpp:23: error: invalid conversion from ¡Ævoid (*)()¡Ç to ¡Ævoid*
(*)(void*)¡Ç
main.cpp:23: error: initializing argument 3 of ¡Æint
pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*),
void*)¡Ç
main.cpp:26: error: cannot convert ¡Æpthread_t**¡Ç to ¡Æpthread_t*¡Ç
for argument ¡Æ1¡Ç to ¡Æint pthread_create(pthread_t*, const
pthread_attr_t*, void* (*)(void*), void*)¡Ç

make: *** [main.o] Error 1
****************************************************************

I tried to change argument 3 of pthread_create to &print_a.


thanks
 
M

Michael

void print_a(){
for ( int i=0; i<10; i++)
cout << "a";
}

void print_b(){
for ( int i=0; i<10; i++)
cout << "b";
}


int main(){

pthread_t thr_a_ID;
pthread_create ( &thr_a_ID, NULL, print_a, NULL );

pthread_t* thr_b_ID;
pthread_create ( &thr_b_ID, NULL, print_b, NULL );
}
//**************** code end ****************

**************** error ****************
main.cpp:23: error: invalid conversion from 'void (*)()' to 'void*
(*)(void*)'
main.cpp:23: error: initializing argument 3 of 'int
pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*),
void*)'
main.cpp:26: error: cannot convert 'pthread_t**' to 'pthread_t*'
for argument '1' to 'int pthread_create(pthread_t*, const
pthread_attr_t*, void* (*)(void*), void*)'

make: *** [main.o] Error 1
****************************************************************

I don't know anything about pthreads, but here's what your compiler is
telling you:

Error on line 23:
print_a needs to look like this:

void* print_a(void* data) {
// Do something and return something
}

Error on line 26:
pthread_t* thr_b_ID;
Get rid of *.

Michael
 
G

Gary Wessle

Michael said:
void print_a(){
for ( int i=0; i<10; i++)
cout << "a";
}

void print_b(){
for ( int i=0; i<10; i++)
cout << "b";
}


int main(){

pthread_t thr_a_ID;
pthread_create ( &thr_a_ID, NULL, print_a, NULL );

pthread_t* thr_b_ID;
pthread_create ( &thr_b_ID, NULL, print_b, NULL );
}
//**************** code end ****************

**************** error ****************
main.cpp:23: error: invalid conversion from 'void (*)()' to 'void*
(*)(void*)'
main.cpp:23: error: initializing argument 3 of 'int
pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*),
void*)'
main.cpp:26: error: cannot convert 'pthread_t**' to 'pthread_t*'
for argument '1' to 'int pthread_create(pthread_t*, const
pthread_attr_t*, void* (*)(void*), void*)'

make: *** [main.o] Error 1
****************************************************************

I don't know anything about pthreads, but here's what your compiler is
telling you:

Error on line 23:
print_a needs to look like this:

void* print_a(void* data) {
// Do something and return something
}

Error on line 26:
pthread_t* thr_b_ID;
Get rid of *.

Michael

thanks,
I fixed the code but it is not doing what I expected it to do, which
is print out aa(s) and bb(s).

//**************** code v 1.0 start ****************
#include <iostream>
#include <ctime>
#include <cstdio>
#include <cstdlib>
#include <pthread.h>

using namespace std;

void* print_a(void* data) {
char* a = (char*) data;
for ( int i=0; i<10; i++)
cout << *a;
}

void* print_b(void* data){
char* b = (char*) data;
for ( int i=0; i<10; i++)
cout << *b;
}


int main(){
char* a = "aa";
void * pva = (void*) a;
pthread_t thr_a_ID;
pthread_create ( &thr_a_ID, NULL, print_a, pva );

char* b = "bb";
void* pvb = (void*) b;
pthread_t thr_b_ID;
pthread_create ( &thr_b_ID, NULL, print_b, pvb );
}
//**************** code v 1.0 end ****************
 
G

Gary Wessle

here is the makefile to run the code

LDFLAGS = -lpthread
CXXFLAGS = -gdwarf-2
OBJS := $(patsubst %.cpp,%.o,$(wildcard *.cpp))
COMP = g++

proj: $(OBJS)
$(COMP) -Wall -gdwarf-2 -o proj $(OBJS) $(LDFLAGS)

#-Wall turns on all warnings
#-gdwarf-2 for dubugging note gdb manual 12.4.1
clean:
rm -rf *.o proj
 
M

Michael

thanks,
I fixed the code but it is not doing what I expected it to do, which
is print out aa(s) and bb(s).

You may need to post this to a pthreads-specific group to get better
help.

Like I said, I don't know anything about pthreads. From a little
googling, though, I came on this site:
http://yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
which leads me to believe you need to do a pthread_join on each of the
two threads you just created. But I could be totally wrong.

Michael
 
S

Salt_Peter

Gary said:
Michael said:
void print_a(){
for ( int i=0; i<10; i++)
cout << "a";
}

void print_b(){
for ( int i=0; i<10; i++)
cout << "b";
}


int main(){

pthread_t thr_a_ID;
pthread_create ( &thr_a_ID, NULL, print_a, NULL );

pthread_t* thr_b_ID;
pthread_create ( &thr_b_ID, NULL, print_b, NULL );
}
//**************** code end ****************

**************** error ****************
main.cpp:23: error: invalid conversion from 'void (*)()' to 'void*
(*)(void*)'
main.cpp:23: error: initializing argument 3 of 'int
pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*),
void*)'
main.cpp:26: error: cannot convert 'pthread_t**' to 'pthread_t*'
for argument '1' to 'int pthread_create(pthread_t*, const
pthread_attr_t*, void* (*)(void*), void*)'

make: *** [main.o] Error 1
****************************************************************

I don't know anything about pthreads, but here's what your compiler is
telling you:

Error on line 23:
print_a needs to look like this:

void* print_a(void* data) {
// Do something and return something
}

Error on line 26:
pthread_t* thr_b_ID;
Get rid of *.

Michael

thanks,
I fixed the code but it is not doing what I expected it to do, which
is print out aa(s) and bb(s).

//**************** code v 1.0 start ****************
#include <iostream>
#include <ctime>
#include <cstdio>
#include <cstdlib>
#include <pthread.h>

using namespace std;

void* print_a(void* data) {
char* a = (char*) data;
for ( int i=0; i<10; i++)
cout << *a;
}

void* print_b(void* data){
char* b = (char*) data;
for ( int i=0; i<10; i++)
cout << *b;
}


int main(){
char* a = "aa";

shouldn't that array have 10 characters?
void * pva = (void*) a;
pthread_t thr_a_ID;
pthread_create ( &thr_a_ID, NULL, print_a, pva );

At this point, since the return values are not collected, main does not
wait for the above thread to be terminated. And neither has the thread
been joined.
char* b = "bb";
void* pvb = (void*) b;
pthread_t thr_b_ID;
pthread_create ( &thr_b_ID, NULL, print_b, pvb );
}
//**************** code v 1.0 end ****************

[Off Topic]

Instead of printing from seperate threads, where a race condition can
diffuse the output if not outright fail, lets have a couple of threads
do a little work instead.

#include <iostream>
#include <pthread.h>

// this function will load a char array[10] with chars from a to j
void* load_carray(void* p_data)
{
char* p_array = static_cast<char*>(p_data);
char c = 'a';
for (int i=0; i< 10; i++)
*(p_array++) = c++;
return 0;
}

// this function loads an int array[10] from 0 to 9
void* load_narray(void* p_data)
{
int* p_narray = static_cast<int*>(p_data);
for (int i=0; i< 10; i++)
*(p_narray++) = i;
return 0;
}

// function prints any array - deduced parameters
template< typename T , const size_t Size>
void print_t(T(&array)[Size])
{
for(size_t i = 0; i < Size; ++i)
{
std::cout << array;
}
std::cout << std::endl;
}

int main()
{
char carray[10] = { 'z' }; // char[] for thread 0
int narray[10] = { 0 }; // int[] fot thread 1
// threadID array and result array
pthread_t threadID[2];
int result[2];
// create threads with PTHREAD_CREATE_JOINABLE - the default
result[0] = pthread_create( &threadID[0],
0, // PTHREAD_CREATE_JOINABLE
load_carray,
carray );
result[1] = pthread_create( &threadID[1],
0, // PTHREAD_CREATE_JOINABLE
load_narray,
narray );
// wait for both threads to be created and complete
pthread_join( threadID[0], 0);
pthread_join( threadID[1], 0);
// display threadID and results
for(int n = 0; n < 2; ++n)
{
std::cout << "threadID " << threadID[ n ];
std::cout << "\nresult: " << result[ n ] << std::endl;
}
// lets see the initialized arrays
print_t( carray );
print_t( narray );

return 0;
}

/*
threadID 1084229952
result: 0
threadID 1094719808
result: 0
abcdefghij
0123456789
*/
 
G

Gary Wessle

Gary Wessle said:
here is the makefile to run the code

LDFLAGS = -lpthread
CXXFLAGS = -gdwarf-2
OBJS := $(patsubst %.cpp,%.o,$(wildcard *.cpp))
COMP = g++

proj: $(OBJS)
$(COMP) -Wall -gdwarf-2 -o proj $(OBJS) $(LDFLAGS)

#-Wall turns on all warnings
#-gdwarf-2 for dubugging note gdb manual 12.4.1
clean:
rm -rf *.o proj

for the records:
the Fix:

#include <iostream>
#include <ctime>
#include <cstdio>
#include <cstdlib>
#include <pthread.h>

using namespace std;

void* print_a(void* data) {
pthread_yield(); // send to end of run queue
cout << "a called\n";
string* a = static_cast<string*> (data);
for ( int i=0; i<10; i++) {
cout << *a;
pthread_yield();
}
cout << "--a finihed\n";
}

void* print_b(void* data){
cout << "b called\n";
string* b = static_cast<string*> (data);
for ( int i=0; i<10; i++) {
cout << *b;
pthread_yield();
}
cout << "--b finihed\n";
}

int main(){

pthread_t thr_a_ID, thr_b_ID;
string a = "aa";
string b = "bb";
int iret1, iret2;
void * pva = static_cast<void*> (&a);
void* pvb = static_cast<void*> (&b);

iret1 = pthread_create ( &thr_a_ID, NULL, print_a, pva );
iret2 = pthread_create ( &thr_b_ID, NULL, print_b, pvb );

pthread_join (thr_a_ID, NULL);
pthread_join (thr_b_ID, NULL);

}
 
G

Gary Wessle

Salt_Peter said:
[Off Topic]

Instead of printing from seperate threads, where a race condition can
diffuse the output if not outright fail, lets have a couple of threads
do a little work instead.

#include <iostream>
#include <pthread.h>

// this function will load a char array[10] with chars from a to j
void* load_carray(void* p_data)
{
char* p_array = static_cast<char*>(p_data);
char c = 'a';
for (int i=0; i< 10; i++)
*(p_array++) = c++;
return 0;
}

// this function loads an int array[10] from 0 to 9
void* load_narray(void* p_data)
{
int* p_narray = static_cast<int*>(p_data);
for (int i=0; i< 10; i++)
*(p_narray++) = i;
return 0;
}

// function prints any array - deduced parameters
template< typename T , const size_t Size>
void print_t(T(&array)[Size])
{
for(size_t i = 0; i < Size; ++i)
{
std::cout << array;
}
std::cout << std::endl;
}

int main()
{
char carray[10] = { 'z' }; // char[] for thread 0
int narray[10] = { 0 }; // int[] fot thread 1
// threadID array and result array
pthread_t threadID[2];
int result[2];
// create threads with PTHREAD_CREATE_JOINABLE - the default
result[0] = pthread_create( &threadID[0],
0, // PTHREAD_CREATE_JOINABLE
load_carray,
carray );
result[1] = pthread_create( &threadID[1],
0, // PTHREAD_CREATE_JOINABLE
load_narray,
narray );
// wait for both threads to be created and complete
pthread_join( threadID[0], 0);
pthread_join( threadID[1], 0);
// display threadID and results
for(int n = 0; n < 2; ++n)
{
std::cout << "threadID " << threadID[ n ];
std::cout << "\nresult: " << result[ n ] << std::endl;
}
// lets see the initialized arrays
print_t( carray );
print_t( narray );

return 0;
}

/*
threadID 1084229952
result: 0
threadID 1094719808
result: 0
abcdefghij
0123456789
*/


thank you.

my point is to see how the 2 threads running concurrently, the setup
above does not show me that. it shows me that one thread runs after
the other finishes. after a bit of reading I realized that both
threads will not run concurrently unless one gives way to the other
which is possible using pthread_yield to put the current thread on the
bottom of the run queue. as this;

#include <iostream>
#include <pthread.h>

using namespace std;

void* print_a(void* data) {
cout << "a called\n";
string* a = static_cast<string*> (data);
for ( int i=0; i<1000; i++) {
cout << *a;
pthread_yield(); // <<<<<<<<<<<<<<<<
}
cout << "--a finihed\n";
}

void* print_b(void* data){
cout << "b called\n";
string* b = static_cast<string*> (data);
for ( int i=0; i<1000; i++) {
cout << *b;
pthread_yield(); // <<<<<<<<<<<<<<<<
}
cout << "--b finihed\n";
}

int main(){

pthread_t thr_a_ID, thr_b_ID;
string a = "aa";
string b = "bb";
int iret1, iret2;
void * pva = static_cast<void*> (&a);
void* pvb = static_cast<void*> (&b);

iret1 = pthread_create ( &thr_a_ID, 0, print_a, pva );
iret2 = pthread_create ( &thr_b_ID, 0, print_b, pvb );

pthread_join (thr_a_ID, 0);
pthread_join (thr_b_ID, 0);

}
 
L

Larry Smith

Gary said:
for the records:
the Fix:

#include <iostream>
#include <ctime>
#include <cstdio>
#include <cstdlib>
#include <pthread.h>

using namespace std;

void* print_a(void* data) {
pthread_yield(); // send to end of run queue
cout << "a called\n";
string* a = static_cast<string*> (data);
for ( int i=0; i<10; i++) {
cout << *a;
pthread_yield();
}
cout << "--a finihed\n";
}

void* print_b(void* data){
cout << "b called\n";
string* b = static_cast<string*> (data);
for ( int i=0; i<10; i++) {
cout << *b;
pthread_yield();
}
cout << "--b finihed\n";
}

int main(){

pthread_t thr_a_ID, thr_b_ID;
string a = "aa";
string b = "bb";
int iret1, iret2;
void * pva = static_cast<void*> (&a);
void* pvb = static_cast<void*> (&b);

iret1 = pthread_create ( &thr_a_ID, NULL, print_a, pva );
iret2 = pthread_create ( &thr_b_ID, NULL, print_b, pvb );

pthread_join (thr_a_ID, NULL);
pthread_join (thr_b_ID, NULL);

}

Actually, threads will be swapped in & out in a normal
program.

pthread_yield() is almost never required in a real-world
multi-threaded program. The thread context changes
will be performed by the Unix/Linux kernel at the most
opportune times. There are reasons that pthread_yield()
is not documented in most recent implementations of
pthreads.

On a multi-processor system, pthread_yield() may actually
cause the program to thrash, as it swaps threads onto/off-of
the various processors.

Your example functions are not representative of
real-life thread functions. Yours perform very little
work in a very tight loop, then exit.
The 1st thread may finish before the 2nd thread
is even started.

Create more realistic thread functions, eg:

- one thread that runs forever monitoring a socket
for input & places the input on a queue.
- one or more threads that monitor the input queue,
remove the data, do something with it, then put
the results on an output queue.
- a thread that watches the output queue, picks new
data off of the output queue, and writes the data
to a socket/file/console.

All of the threads above should run forever (as long as the
program is running). Mutexes will be required to
control both read & write access to the various queues.

You may get additional help on threading in other
newsgroups:

comp.programming.threads
comp.os.linux.development.apps
comp.os.linux.development.system

Larry
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top