Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 1 year ago.
Improve this question
I'm supposed to be generating a program that creates a thread that generates a random number between 0 and 1 and prints out the generated random number.
The error messages I'm receiving from Xcode don't make any logical sense. I tried many different methods, I might just be overlooking it but I could don't see any possible syntax errors
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
void printMsg(char* msg) {
int status = 0;
printf("%s\n", msg);
pthread_exit(&status);
}
int main(int argc, char** argv) {
pthread_t thrdID;
int* status = (int*)malloc(sizeof(int));
printf("creating a new thread\n");
pthread_create(&thrdID, NULL, (void*)printMsg, argv[1]);
printf("created thread %d\n". thrdID);
pthread_join(thrdID, &status);
printf("Thread %d exited with status %d\n", thrdID, *status);
return 0;
}
Oh, I see it now, you had a period instead of a comma here:
printf("created thread %d\n". thrdID);
should be
printf("created thread %d\n", thrdID);
It was pointed out in some now deleted comments, that there were other issues with the code that should be corrected.
These are some suggestions about how to deal with these issues:
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
void printMsg(char* msg) {
// The stack of the thread will be destryed on exit
// so you need to allocate the status value (or do some
// rather dubious casting... this is cleaner).
int* status_pointer = malloc(sizeof(int));
printf("%s\n", msg);
// For demonstration purposes set it to something other than 0.
*status_pointer = 123;
pthread_exit(status_pointer);
}
int main(int argc, char** argv) {
pthread_t thrdID;
void* status = NULL;
printf("creating a new thread\n");
// You should not blindly pass argv[1] without checking it's valid.
// You can provide a default value like I did below, or error out.
char *msg = argc > 1 ? argv[1] : "This is a default message.";
pthread_create(&thrdID, NULL, (void*)printMsg, msg);
// thrdId is pointer so use the %p format specifier.
printf("created thread %p\n", thrdID);
pthread_join(thrdID, &status);
// same issue with %p
printf("Thread %p exited with status %d\n", thrdID, *(int*)status);
// don't forget to free what you allocated.
free(status);
return 0;
}
Related
I am learning threads using C and found the following 'Hello World' program. When I am printing the vale of pthread_value() within the thread and outside the thread using pthread_join() the values returned by the two threads are completely different.
/******************************************************************************
* FILE: hello.c
* DESCRIPTION:
* A "hello world" Pthreads program. Demonstrates thread creation and
* termination.
* AUTHOR: Blaise Barney
* LAST REVISED: 08/09/11
******************************************************************************/
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 5
void *PrintHello(void *threadid)
{
long tid;
tid = (long)threadid;
printf("Hello World! It's me, thread #%ld!, %ld\n", tid, pthread_self());
long a= pthread_self();
//pthread_exit(NULL);
long *p = &a;
return p;
}
int main(int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
void *status;
long t;
FILE* file = fopen("test.txt", "r");
for(t=0;t<NUM_THREADS;t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
for(t=0; t<NUM_THREADS;t++){
pthread_join(threads[t], &status);
printf("%ld\n",(long)status);
}
/* Last thing that main() should do */
pthread_exit(NULL);
}
Your PrintHello() function returns the address of a local variable. Trying to use that address after the function exits is undefined and anything can happen, from getting a garbage value to your program crashing. Plus instead of dereferencing that address to get at the value it points to (Assuming it was still valid, which, again, it's not), you cast the address to a long and print out the address itself. I doubt that's what you intended to do. The general approach should be to malloc enough memory in the thread to hold its return value, and returning that address. Then in the joining thread, dereference that returned address to get at the actual returned value, and free that memory when done.
Hi i'm just trying to use posix_spawn on OSX , this should work find (as for *nix) anyway after posix_spawn syscall the process will receive SIGTRAP i really cannot uderstand why.
#include <spawn.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
while(1){
char *newargv[] = { "/usr/bin/id", 0 };
char *newenviron[] = {0};
posix_spawnattr_t * a;
posix_spawn_file_actions_t * fa;
fa = malloc(0x80);
a = malloc(336);
//printf("size: %d\n", sizeof(posix_spawnattr_t));
posix_spawnattr_init(a);
posix_spawnattr_setflags(a, 0x40);
posix_spawn_file_actions_init(fa);
pid_t pid;
int status = 0;
posix_spawn(&pid, "/usr/bin/id", fa, a, newargv, newenviron);
waitpid(pid, &status, 0);
printf("pid: %d\n", pid);
}
//printf("pid: %d\n", pid);
return 0;
}
It should run forever but the output from id will be printed just one time.
Thanks for your support!
Not sure what you are actually trying to do, because you have hard-coded constants and sizes in that may not be relevant on macOS.
The main problem is that your 0x40 flag means that /usr/bin/id is exec'ed - just once and replaces the current process so it doesn't go around the loop again!
Other problems should be visible from the version below:
#include <spawn.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *newargv[] = { "/usr/bin/id", 0 };
char *newenviron[] = {0};
posix_spawnattr_t a;
posix_spawnattr_init(&a);
// posix_spawnattr_setflags(&a, 0x40); exec & replace the current process !!!
pid_t pid;
int status = 0;
while(1){
posix_spawn(&pid, "/usr/bin/id", NULL, &a, newargv, newenviron);
waitpid(pid, &status, 0);
printf("pid: %d\n", pid);
}
return 0;
}
The difference between what you have:
posix_spawnattr_t * a;
a = malloc(336);
and what I have:
posix_spawnattr_t a;
is that firstly, mine is the correct size no matter how the structure is defined on any particular OS, whereas yours is a hard-coded number that may or may not be correct for any particular OS, and secondly, your method leaks 336 bytes of memory every time through the loop which, given that there is no delay or anything else in the loop, might mean more of a gushing tap/faucet than a minor leak ;-)
I want to use a bunch of pthreads in my application. To get familiar with the pthread library, I started with a small demo application (see attached sourcecode).
If I create 200 threads, all works well. However, if I increase the number of threads to 2000 the application crashes with a segfault. According to gdb the segfault happens at pthread_join. Unfortunately I could'nt figure out why this is happening.
First, I thought, that my linux machine could'nt handle that many threads, so I increased the value in /proc/sys/kernel/threads-max, but that didn't change anything.
What am I doing wrong?
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define THREADS 200 //If I increase this value to 2000, the application crashes with a segfault
struct tInfo_t{
int sockfd;
};
pthread_t workerThreads[THREADS];
struct tInfo_t tInfo[THREADS];
void *handle(void *arg){
struct tInfo_t threadArgs = *((struct tInfo_t*)arg);
pthread_exit(0); //do nothing, just exit
return NULL; //to make the compiler happy
}
int main(int argc, char *argv[])
{
int i = 0;
//create a few threads
for(i = 0; i < THREADS; i++){
if(pthread_create(&workerThreads[i], 0, handle, (void*)&tInfo[i]) == -1){
printf("couldn't create thread. %d \n", workerThreads[i]);
return EXIT_FAILURE;
}
printf("Thread #%d spawned\n", i);
}
//wait until all threads finished their job
for(i = 0; i < THREADS; i++){
pthread_join(workerThreads[j], NULL);
}
return EXIT_SUCCESS;
}
I am working a c- project which uses semaphores to handle the same function at the same time. When I run it, on linux, under the root user, it works perfect. But if I run it on another user, the script isn't executed and it leaves a semaphore in the semaphore array. Does anybody know a solution to this problem?
Here is my code:
int main(int argC, char* argv[]) {
pthread_t thr[argC-1];
int indexes[argC-1];
int i,j;
for(j=0; j<(argC-1); j++) {
indexes[j] = atoi(argv[j+1]);
pthread_create (&thr[j], NULL, (int *) &stabtest, (void *) &indexes[j]);
}
sem_init(&mutex, 0, 1);
for(j=0; j<(argC-1); j++) pthread_join(thr[j], NULL);
// Destroy semaphore
sem_destroy(&mutex);
// Exit
exit(0);
}
int stabtest(void *ptr) {
sem_wait(&mutex); // down semaphore
// Other code ...
sem_post(&mutex); // up semaphore
pthread_exit(0); // exit thread
}
This code I actually found on the internet because I have no experience with semaphores. So I am not sure of this code is the right one to run the function in parallel at the same time. But it works for the root user, so I guess the code is more or less ok.
Thank you!
If this is the code you are using, whatever you think is happening isn't happening. Permissions should have no effect on the semaphore you are using. And there is no semaphore array, you are using a single semaphore.
You seem to have a shaky grasp on command line parms. They are an array pointers to string. argc is the number of arguments. There will always be at least 1 argv, argv[0], which is the program name. Please don't rename argc. Everyone knows what argc is. Renaming it will just annoy people.
You start your threads and then you initialize your semaphore. That's a problem.
The start function of a pthread has to have the signature void* stabtest(void *ptr). Yours is int stabtest(void *ptr) and you are trying to cast your way out of a mistake. Don't do that. If you want to return something from a thread you do it through the void ptr used as the 4th parm in pthread_create. That is, allocate some memory, pass it in pthread_create, do whatever you need to in the thread to change the information pointed to, and then return the same void ptr from the thread. When you do your pthread_join you can access the returned pointer to the data in the second paramater in pthread_join.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
sem_t mutex;
void* stabtest(void *ptr)
{
sem_wait(&mutex); // down semaphore
printf("in thread %lu...\n", pthread_self());
sem_post(&mutex); // up semaphore
pthread_exit(0); // exit thread
}
int main(int argc, char* argv[])
{
if (argc != 2)
{
printf("usage: %s numThread\n", argv[0]);
exit(1);
}
int maxThreads = atoi(argv[1]);
pthread_t thr[maxThreads];
int indexes[maxThreads];
int i, j;
sem_init(&mutex, 0, 1);
for (j = 0; j < maxThreads; j++)
pthread_create (&thr[j], NULL, stabtest, NULL);
for (j = 0; j < maxThreads; j++)
pthread_join(thr[j], NULL);
// Destroy semaphore
sem_destroy(&mutex);
// Exit
exit(0);
}
This question already has an answer here:
Thread created (detached) never executed
(1 answer)
Closed 9 years ago.
I'm trying to compile and run the following code using Detached Threads in C Linux. The thing is that I want every thread to show me the corresponding printf from the handler *idThreadMethod and it doesn't show me anything! I tried using a printf before calling the pthread_create function and it shows it, but the problem should be inside the *idThreadMethod (handler function). The code:
//gcc detachedThreads.c -lpthread -o p
//./p 4
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int i;
void *idThreadMethod(void *args)
{
int pid;
pid = *((int *)args);
printf("\nI'm The Detached Thread %d\n", i);
printf("\nMy PID is: %d\n", pid);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
int quantityThreads, returnThread, pid;
pthread_t idThread[15];
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
if(argc-1 < 1)
{
printf("\nSome arguments are missing\n");
return EXIT_FAILURE;
}
quantityThreads = atoi(argv[1]);
pid=getpid();
int *it = &pid;
for(i=0;i<quantityThreads;i++)
{
returnThread = pthread_create(&idThread[i],&attr,idThreadMethod,it);
if(returnThread == -1)
{
printf("\nThere is an error trying to create the thread\n");
return EXIT_FAILURE;
}
}
return EXIT_SUCCESS;
}
What could I do in order to show the printf messages from the *idThreadMethod function?
In main, use pthread_exit. Your main is exiting and thus the rest of your threads die, detached or not.
They're not showing because your main thread is exiting before they even get a chance to printf. As your threads are detached, you cannot use pthread_join to wait for them to do their thing, so you'll need some other form of synchronisation.
Seems to me, you don't really want detached threads at all....