When I try to compile this I get an error:
warning: passing argument 1 of pthread_create makes pointer from integer without a cast.
Please if anyone can help me..
int Traveler(int id, int numBags)
{
int i;
int err;
err = pthread_create(id, NULL, Traveler, NULL);
if(err!=0)
{
return -1;
}
else
{
}
}
The error is pretty clear. The first argument should be a pointer rather than an integer.
man pthread:
int pthread_create(pthread_t *restrict thread,
const pthread_attr_t *restrict attr,
void *(*start_routine)(void*), void *restrict arg);
The pthread_create() function shall create a new thread, with
attributes specified by attr, within a process. If attr is NULL, the
default attributes shall be used. If the attributes specified by attr
are modified later, the thread's attributes shall not be affected. Upon
successful completion, pthread_create() shall store the ID of the cre-
ated thread in the location referenced by thread.
Re-read that last sentence before sticking an ampersand before id in your pthread_create call. EDIT2: you will also have to define id as a pthread_t.
EDIT:
Actually, there are two other issues on the same line: start_routine needs to be a function that takes one argument rather than two, but worst of all this would be a fork bomb since you're passing the same function you're calling from!
Related
I know that I can return that parameter can't be nil by NSError or throw NSException, but what is the best option to inform that parameter can't be nil in objective-c ?
Documentation.
Use assertions to raise exceptions during development.
Return an NSError too (though it should hopefully never happen by the time you get to production).
You could use NSAssert(), which will only fire in builds where NS_BLOCK_ASSERTIONS is not defined:
- (void)someMethodWithParam:(id)someParam {
NSAssert(someParam, #"someParam cannot be nil");
...
}
That will pretty much restrict the checking to you, and fellow developers, but if you want it to persist, regardless of build, then an NSException is best:
- (void)someMethodWithParam:(id)someParam {
if (!someParam) {
[NSException raise:#"MyException" format:#"someParam cannot be nil"];
}
...
}
To check at compile time use
__attribute__ with nonnull
Example, first and second parameters should not be null:
extern void * my_memcpy (void *dest, const void *src, size_t len)
__attribute__((nonnull (1, 2)));
The nonnull attribute specifies that some function parameters should
be non-null pointers. Using nonnull encodes expectations about values
into an explicit contract, which can help catch any NULL pointer bugs
lurking in any calling code. Remember: compile-time errors ≫ run-time
errors.
Read more here
Is there an easy way to create a new pthread each time a method is called?
I have a method activating in certain circumstances and it is the only way to commumicate with another program. I need to engage sleep and execute another method after said method is called, there is an option of another call during waiting - this is the reason i wanted to use threads.
I wanted to use standard:
pthread_create(&new_thread, NULL, threadbody() );
Put like this
std::vector<phtread_t> thread(20)
...
pthread_t new_thread;
int rc;
rc = pthread_create(&new_thread, NULL, threadbody() );
threads.push_back(new_thread);
But i either get the errors of bad using of (void *) functions.
argument of type ‘void* (App::)(void*)’ does not match ‘void* (*)(void*)
What am I doing wrong?
Your function is a non-static member of the class. This is a no-no since pthread_create is only meant to work in the C realm.
To offset this, you can have
class X
{
public:
static void* callback(void* p)
{
X* x = reinterpret_cast<X*>(p);
x->function();
return 0;
}
void function(void)
{
// do work here
}
};
X obj;
pthread_create(&new_thread, &obj, &X::callback);
Assume such conditions:
Some operation does not provide possibility of returning the result.
This operation declared as callback
Using typedef not recommended
Some operation provide of returning the result.
This operation declared as callback
Using typedef not recommended
Assume such scenario:
void main() {
executeVoidOperation(methodNonVoid); // Must throw if method void?
executeNonVoidOperation(methodVoid); // Must throw if method non-void?
}
int methodNonVoid() {
return 0;
}
void methodVoid() {
}
void executeVoidOperation(void operation()) {
operation(); // Must throw if method non-void?
}
void executeNonVoidOperation(dynamic operation()) {
var result = operation(); // Must throw if method void?
print(result); // Result of void operation? (if such passed as argument)
}
Displayed results:
null
Questions (where I wrong?):
Null is object. From where this null appeared (as result) if void function cannot return result (even null)?
Functions with different return types in Dart assumed as the same (not conflicting) types?
How in Dart called this function transformations?
executeNonVoidOperation(methodVoid); works because the callback is defined as dynamic operation(). dynamic can be anything, including void. It's the same as if you just don't specify a type.
The null value stems from a simple rule in Dart. Quoted from the Dart Language Tour:
All functions return a value. If no return value is specified, the statement return null; is implicitly appended to the function body.
That means that every void method always returns null. If you try to return something else, you'll get a runtime error (in checked mode).
executeVoidOperation(methodNonVoid); is a bit more tricky - I'd expect it to throw a runtime error, but it seems the callback is treated as dynamic operation() instead of void operation(). Dart Editor's analyzer seems to think that, too. This may be either a bug or a design choice by the Dart team.
I want to call a c function from objective-c and pass objective-c function as a callback
the problem is this function has a callback as parameter, so I have to pass objective-c function as a call back to c function
here is the header of the c function
struct mg_context *mg_start(const struct mg_callbacks *callbacks,
void *user_data,
const char **configuration_options);
here is where I try to call it
- (void)serverstarted
{
NSLog(#"server started");
}
- (IBAction)startserver:(id)sender {
NSLog(#"server should start");
const char *options[] =
{
"document_root", "www",
"listening_ports", "8080",
NULL
};
mg_start(serverstarted(), NULL, options);
}
I have tried several ways to do it and searched the web to just get a clue how to do it but with not luck
here is the library I am incuding in my code
https://github.com/valenok/mongoose
Your chief problem is the first parameter to mg_start(), which is described in the declaration as const struct mg_callbacks *callbacks. You are trying pass a pointer to a function. (Actually you are trying to pass the result of a call to that function, which is even further from the mark.) That isn't what it says: it says a pointer to a struct (in particular, an mg_callbacks struct).
The example code at https://github.com/valenok/mongoose/blob/master/examples/hello.c shows you how to configure this struct. You have to create the struct and put the pointer to the callback function inside it. Then you pass the address of that struct.
Other problems with your code: your callback function itself is all wrong:
- (void)serverstarted
{
NSLog(#"server started");
}
What's wanted here is a C function declared like this: int begin_request_handler(struct mg_connection *conn), that is, it takes as parameter a pointer to an mg_connection struct. Your serverstarted not only doesn't take that parameter, it isn't even a C function! It's an Objective-C method, a totally different animal. Your use of the term "Objective-C function" in your title and your question is misleading; C has functions, Objective-C has methods. No Objective-C is going to be used in the code you'll be writing here.
What I suggest you do here is to copy the hello.c example slavishly at first. Then modify the content / names of things slowly and bit by bit to evolve it to your own code. Of course learning C would also help, but you can probably get by just by copying carefully.
As matt already said, you cannot pass an Objective-C method as callback where a C function
is expected. Objective-C methods are special functions, in particular the receiver ("self")
is implicitly passed as first argument to the function.
Therefore, to use an Objective-C method as request handler, you need an (intermediate) C function as handler and you have to pass self to that function, using the user_data argument. The C function can then call the Objective-C method:
// This is the Objective-C request handler method:
- (int)beginRequest:(struct mg_connection *)conn
{
// Your request handler ...
return 1;
}
// This is the intermediate C function:
static int begin_request_handler(struct mg_connection *conn) {
const struct mg_request_info *request_info = mg_get_request_info(conn);
// Cast the "user_data" back to an instance pointer of your class:
YourClass *mySelf = (__bridge YourClass *)request_info->user_data;
// Call instance method:
return [mySelf beginRequest:conn];
}
- (IBAction)startserver:(id)sender
{
struct mg_callbacks callbacks;
memset(&callbacks, 0, sizeof(callbacks));
callbacks.begin_request = begin_request_handler;
const char *options[] =
{
"document_root", "www",
"listening_ports", "8080",
NULL
};
// Pass "self" as "user_data" argument:
mg_start(&callbacks, (__bridge void *)self, options);
}
Remarks:
If you don't use ARC (automatic reference counting) then you can omit the (__bridge ...)
casts.
You must ensure that the instance of your class ("self")
is not deallocated while the server is running. Otherwise the YourClass *mySelf
would be invalid when the request handler is called.
Need urgent help on thread: the goal here is the separtemask will take each image and separate different contours and for each contour in the image it will call handleobject thread. So every for loop will call the handeobject thread. However, object index variable needs to be passed in each thread. But only last value of objectndex is passed, this is becuase the speratemask function loops and repalces the value of obj.objindx and only the last value of obj.objindx is
passed to all the threads. Is there anyway to pass each objectindex
value in handleobject. The code runs fine if we uncomment the pthread_join(tid[objectIndex],NULL); but it will not give a parralel program
void separateMask(IplImage *maskImg)
{
for(r = contours; r != NULL; r = r->h_next)
{
cvSet(objectMaskImg, cvScalarAll(0), NULL);
CvScalar externalColor = cvScalarAll(0xff);
CvScalar holeColor = cvScalarAll(0x00);
int maxLevel = -1;
int thinkness = CV_FILLED;
int lineType = 8; /* 8-connected */
cvDrawContours(objectMaskImg, r, externalColor, holeColor, maxLevel, thinkness,lineType, cvPoint(0,0));;
obj.objectMaskImg1[objectIndex]=(IplImage *) malloc(sizeof(IplImage));
obj.objectMaskImg1[objectIndex]=objectMaskImg;
obj.objindx=objectIndex;
obj.intensityOut1=intensityOut;
obj.tasOut1=tasOut;
pthread_create(&tid[objectIndex],NULL,handleObject,(void *)&obj);
//pthread_join(tid[objectIndex],NULL);
printf("objectindx %d\n",obj.objindx);
objectIndex++;
}
// cvReleaseImage(&objectMaskImg);
//cvReleaseMemStorage(&storage);
printf("Exitng Separatemask\n");
}
void* handleObject(void *arg)
{
int i, j;
handle *hndl;
hndl=(handle *) malloc(sizeof(handle));
hndl=(handle*)arg;
pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&lock);
IplImage *pImg;
float statistics_ratio[3][9];
pthread_t tid3;
tas3 tas2;
pImg = cvLoadImage("image.tif", CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH);
if(pImg == NULL)
{
fprintf(stderr, "Fail to load image %s\n", "tiff file");
return ;
}
tas2.pImg1=pImg;
printf("tst%d\n",hndl->objindx);
tas2.x=hndl->objindx;
tas2.objectMaskImg1=hndl->objectMaskImg1[tas2.x];
tas2.statistics_ratio[3][9]=statistics_ratio[3][9];
double mean = average_intensity(pImg, tas2.objectMaskImg1);
int total = total_white(pImg, tas2.objectMaskImg1);
pthread_mutex_unlock(&lock);
printf("Exiting handle object thread_id %d\n\n", pthread_self());
}
This function appears to have issues
void* handleObject(void *arg)
Firstly
pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&lock);
this is a locally created mutex - but created WITHIN the thread function. So you lock it but since nothing else can see the mutex, why do you need it??? It gives no synchronization functionality if no other threads can see it.
Secondly
float statistics_ratio[3][9];
pthread_t tid3;
tas3 tas2;
pImg = cvLoadImage("image.tif", CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH);
if(pImg == NULL){
fprintf(stderr, "Fail to load image %s\n", "tiff file");
return ;
}
tas2.pImg1=pImg;
printf("tst%d\n",hndl->objindx);
tas2.x=hndl->objindx;
tas2.objectMaskImg1=hndl->objectMaskImg1[tas2.x];
tas2.statistics_ratio[3][9]=statistics_ratio[3][9];
you create a local uninitialised 2d float array statistics_ratio, do nothing with it then assign it to another locally created object member. This appears to be meaningless, as does the declaration of another pthread instance tid3.
It doesn't really matter since nothing else can see the thread but you return from inside this function if pImg == NULL without first unlocking the mutex.
It is very hard to see why your code doesnt work or what it is meant to do, but perhaps the things highlighted above may help. You are creating a lot of local variables within your thread functions which are not being used. I am not sure if you need some of these to be global instead - particularly the mutex (if indeed you need one at all).
I think your initial problem is that you're reusing the obj structure that you're passing to the created threads so you'll have data races where the thread just created will read information that's been overwritten with data intended for another thread.
The loop that creates the threads has the following structure:
for(r = contours; r != NULL; r = r->h_next)
{
// initialize obj with information for the thread
// ...
// create a thread and pass it a pointer to obj
pthread_create(&tid[objectIndex],NULL,handleObject,(void *)&obj);
// some other bookkeeping
}
Since you immediately re-initialize obj on the next loop iteration, who knows what data the thread function is going to get? That's why things work if you join the thread after creating it - the obj structure remains stable because the loop blocks until the thread is finished.
Change the loop to look something like:
for(r = contours; r != NULL; r = r->h_next)
{
// instead of using `obj`, allocate a struct using malloc
handle* threaddata = malloc(sizeof(handle); // note: I'm not sure if `handle` is the right type
// initialize *threaddata with information for the thread
// ...
// create a thread and pass it the threaddata pointer
pthread_create(&tid[objectIndex],NULL,handleObject,threaddata);
// some other bookkeeping
}
Then free() the data in the thread function after it is finished with with (ie., the thread creation code creates and initializes the block of data then passes ownership of it to the thread).
Note that this might not be as straightforward as it often is, becuase it looks like your obj structure already has some per-thread information in it (the objectMaskImg1 element looks to be an array it each element being intended for a separate thread). So you might need to do some refactoring of the data structure as well.
Finally, there are several other outright bugs such as immediately overwriting pointers to blocks allocated by malloc():
obj.objectMaskImg1[objectIndex]=(IplImage *) malloc(sizeof(IplImage));
obj.objectMaskImg1[objectIndex]=objectMaskImg;
and
hndl=(handle *) malloc(sizeof(handle));
hndl=(handle*)arg;
In addition to the pointless use of the mutex in the handleObject() thread function as mentioned by mathematician1975 (http://stackoverflow.com/a/11460092/12711).
A fair bit of the code in the thread function (copying or attempting to copy data locally, the mutex) appears to be stuff thrown in to try to fix problems without actually understanding what the problem is. I think you really need to get an understanding of where various data lives, how to copy it (as opposed to just copying a pointer to it), and how to manage the ownership of the data.