Learning about pthreads, but I'm having trouble getting them created. Here is my output and the gdb information:
In main(), creating thread 1
ERROR: return code from pthread_create() is 22 for thread 1
In main(), creating thread 2
ERROR: return code from pthread_create() is 22 for thread 2
In main(), creating thread 3
ERROR: return code from pthread_create() is 22 for thread 3
In main(), creating thread 4
ERROR: return code from pthread_create() is 22 for thread 4
In main(), creating thread 5
ERROR: return code from pthread_create() is 22 for thread 5
Program received signal SIGSEGV, Segmentation fault. 0xb7fb4d8a in
pthread_join (threadid=76038327, thread_return=0x0)
at pthread_join.c:46 46 pthread_join.c: No such file or directory.
And here is my code:
#include <stdlib.h>
#include <stdio.h>
#include <strings.h>
#include <errno.h>
#include <pthread.h>
#include <unistd.h>
#define SBUFSIZE 1025
char errorstr[SBUFSIZE];
FILE* inputfp[5];
void* f(void* inpFile) {
fprintf(stderr, "%s\n", (char*)inpFile);
return NULL;
}
int main (int argc, char* argv[]) {
int i;
/* Thread Variables */
pthread_attr_t attr;
pthread_t *th[argc-2]; //one thread for each input file
/* allocate memory for the threads */
for (i = 0; i < (argc-2); i++) {
th[i] = (pthread_t *) malloc(sizeof(pthread_t));
inputfp[i] = fopen(argv[i], "r");
if (!inputfp[i]) {
sprintf(errorstr, "Error Opening Input File: %s", argv[i]);
perror(errorstr);
}
}
/* Create one thread for each input file */
for (i = 1; i < (argc - 1); i++) {
fprintf (stderr, "In main(), creating thread %1d\n", i);
int rc = pthread_create (th[i], &attr, f, inputfp[i-1]);
if (rc) {
printf("ERROR: return code from pthread_create() is %d for thread %d\n",
rc, i);
}
}
/* wait for the threads to finish */
for (i = 1; i < (argc - 1); i++) {
pthread_join(*th[i], 0);
}
return EXIT_SUCCESS;
}
I'm missing something, but I don't know what. Can anyone help? Thank you!
EDIT: Here is how I changed the code per the suggestion from Joachim Pileborg. I'm still getting error 22 returning from pthread_create(), but the SIGSEGV error on pthread_join is no longer occurring.
Anyone have any suggestions about how I can get the pthread_create() to return 0 (indicating a successful thread creation)? Thanks again!
int main (int argc, char* argv[]) {
int i;
/* Thread Variables */
pthread_attr_t attr;
pthread_t *th[argc-2]; //one thread for each input file
/* allocate memory for the threads */
for (i = 0; i < (argc-2); i++) {
th[i] = (pthread_t *) malloc(sizeof(pthread_t));
printf("%s\n", argv[i+1]);
inputfp[i] = fopen(argv[i+1], "r");
if (!inputfp[i]) {
sprintf(errorstr, "Error Opening Input File: %s", argv[i]);
perror(errorstr);
}
}
/* Create one thread for each input file */
for (i = 0; i < (argc - 2); i++) {
fprintf (stderr, "In main(), creating thread %1d\n", i);
int rc = pthread_create (th[i], &attr, f, inputfp[i]);
if (rc) {
printf("ERROR: return code from pthread_create() is %d for thread %d\n",
rc, i);
}
}
/* wait for the threads to finish */
for (i = 0; i < (argc - 2); i++) {
pthread_join(*th[i], 0);
}
return EXIT_SUCCESS;
}
You have one loop where you loop from zero to argc - 3, and uses the correct indexes (zero to "size of array minus one".
Then you have two loops where you loop from one to argc - 2, and use indexes from one to "size of array".
You should use the same loop as the first one in all three places.
Related
#include<pthread.h>
#include<stdio.h>
#include<stdint.h>
#include<stdlib.h>
#include<time.h>
#include<unistd.h>
#define ERROR_CREATE 1
#define ERROR_JOIN 2
// create the function to be executed as a thread
void *thread(void *ptr)
{
uintptr_t type = (uintptr_t) ptr; // thread number
srand(time(NULL) + getpid());
int wait = rand() % 10; // randomizes numbers from 0 to 10
sleep(wait); // waits in time intervals of seconds
printf("Thread - %ld waiting for %d seconds\n",type, wait);
return ptr; // returns the thread number
}
int main(int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "Error with command line arguments");
}
int num_threads = atoi(argv[1]);
pthread_t threads[num_threads]; // array of thread types
for (long i = 1; i <= num_threads; i++) {
if (pthread_create(&threads[i], NULL, thread, (void *)i) != 0)
// if there's an error creating thread
{
fprintf(stderr,"Error: could not create thread");
return ERROR_CREATE;
}
}
// terminate each thread assigned
for (int i = 1; i <= num_threads; i++) {
if (pthread_join(threads[i], NULL) != 0)
// if there's an error ending each thread
{
fprintf(stderr, "Error: could not terminate thread");
return ERROR_JOIN;
}
}
return 0;
}
Seeding the rand function, I am still getting the same number outputted. I understand the hardware is fast and therefore is getting the same answer as the clock speed is faster than seeding the rand function. Does anyone know another way of getting more variety from the rand function?
Return if argv[1] is not populated otherwise it segfaults.
srand() resets the sequence. As you call it multiple times with the same value this is not what you want. Moved it main().
The array threads is accessed out of bounds in the two loops.
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#define ERROR_CREATE 1
#define ERROR_JOIN 2
// create the function to be executed as a thread
void *thread(void *ptr) {
uintptr_t type = (uintptr_t) ptr; // thread number
int wait = rand() % 10; // randomizes numbers from 0 to 10
sleep(wait); // waits in time intervals of seconds
printf("Thread - %ld waiting for %d seconds\n",type, wait);
return ptr; // returns the thread number
}
int main(int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "Error with command line arguments\n");
return 1;
}
srand(time(NULL));
int num_threads = atoi(argv[1]);
pthread_t threads[num_threads]; // array of thread types
for (long i = 0; i < num_threads; i++) {
if (pthread_create(&threads[i], NULL, thread, (void *)i) != 0)
// if there's an error creating thread
{
fprintf(stderr,"Error: could not create thread");
return ERROR_CREATE;
}
}
// terminate each thread assigned
for (int i = 0; i < num_threads; i++) {
if (pthread_join(threads[i], NULL) != 0)
// if there's an error ending each thread
{
fprintf(stderr, "Error: could not terminate thread");
return ERROR_JOIN;
}
}
}
and here is a couple of sample runs:
$ ./a.out 2
Thread - 1 waiting for 3 seconds
Thread - 2 waiting for 7 seconds
$ ./a.out 2
Thread - 1 waiting for 3 seconds
Thread - 2 waiting for 6 seconds
I'm using Linux to learn semaphore, trnna test the function sem_init. The code seems simple but the error is unexpected, don't know why. Here's the code and the errors is below the code.
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include<unistd.h>
#include <stdlib.h>
#define NITER 1000000
int cnt = 0;
sem_t mutex;
sem_init(&mutex,0,1);
void * Count(void * a)
{
int i, tmp;
for(i = 0; i < NITER; i++)
{
sem_wait(&mutex);
tmp = cnt; /* copy the global cnt locally */
tmp = tmp+1; /* increment the local copy */
cnt = tmp; /* store the local value into the global cnt */
sem_post(&mutex);
}
}
int main(int argc, char * argv[])
{
pthread_t tid1, tid2;
if(pthread_create(&tid1, NULL, Count, NULL))
{
printf("\n ERROR creating thread 1");
exit(1);
}
if(pthread_create(&tid2, NULL, Count, NULL))
{
printf("\n ERROR creating thread 2");
exit(1);
}
if(pthread_join(tid1, NULL)) /* wait for the thread 1 to finish */
{
printf("\n ERROR joining thread");
exit(1);
}
if(pthread_join(tid2, NULL)) /* wait for the thread 2 to finish */
{
printf("\n ERROR joining thread");
exit(1);
}
if (cnt < 2 * NITER)
printf("\n BOOM! cnt is [%d], should be %d\n", cnt, 2*NITER);
else
printf("\n OK! cnt is [%d]\n", cnt);
pthread_exit(NULL);
}
my english is bad, if anything is hard to understand please tell me and ill respond you as soon as possible!thx
You can declare variables outside the main and the other function which mean that the variable is global .
But to call the function sem_init(&mutex,0,1); you should do it from the main or from another function. In your case , you have to do it in the main.
After moving the sem_init inside the main it compile
nabil#DESKTOP-8ECTID4:~/stackoverflow$ gcc bad.c -o bad -lpthread
nabil#DESKTOP-8ECTID4:~/stackoverflow$
I'm trying to write a program which will spawn an arbitrary number of threads, similar to the code I have in Convert a process based program into a thread based version?, which uses processes to do what I'm trying to accomplish, so far I have the following code, I'm getting a lot of warnings currently, but I'm really wondering if I'm approaching what I'm trying to do somewhat correctly.
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
void *runner(void *param); //the thread
int main(int argc, char *argv[]) {
pthread_t tid = gettid();
pthread_attr_t attr;
if (argc != 2){
fprintf(stderr, "Usage: a.out <integer value>\n");
return -1;
}
if (atoi(argv[1]) < 0) {
fprintf(stderr, "Argument %d must be non negative\n", atoi(argv[1]));
return -1;
}
printf("My thread identifier is: %d\n", tid);
// default attributes
pthread_attr_init(&attr);
// create the thread
pthread_create(&tid, &attr, runner, argv[1]);
// wait for the thread to exit
pthread_join(tid, NULL);
}
void *runner(void *param){
//int i, upper = atoi(param);
int i;
srand48(gettid());
int max = nrand()%100;
if (max > 0){
for (i=1; i<=max; i++){
printf("Child %d executes iteration\n", param, i);
}
}
pthread_exit(0);
}
Appreciate any guidance I can get with this!
If I understand your objective, you want to create the number of threads as the command line parameter indicates.
(remembering that any specific OS can only support a fixed number of threads, which varies depending on the OS, so I will not validate the magnitude that number here.)
the following proposed code:
cleanly compiles
performs the desired functionality
documents why each header file is included
checks for error indications returned from C library functions, like pthread_create()
and now the proposed code:
#include <stdio.h> // printf(), perror(), NULL
#include <pthread.h> // pthread_create(), pthread_join(), pthread_t
#include <stdlib.h> // exit(), EXIT_FAILURE, atof()
void *runner(void *param); //the thread
int main(int argc, char *argv[])
{
if (argc != 2)
{
fprintf(stderr, "Usage: %s <integer value>\n", argv[0]);
exit( EXIT_FAILURE );
}
// might want to use: `strtol()` rather than `atoi()`
// so can check for errors
size_t maxThreads = (size_t)atoi(argv[1]);
pthread_t tid[ maxThreads ];
for( size_t i=0; i<maxThreads; i++ )
{
tid[i] = 0;
}
// create the threads
for( size_t i=0; i<maxThreads; i++ )
{
if( pthread_create( &tid[i], NULL, runner, (void *)i ) )
{
perror( "pthread_create failed" );
}
}
// wait for each thread to exit
for( size_t i = 0; i<maxThreads; i++ )
{
// if thread was created, then wait for it to exit
if( tid[i] != 0 )
{
pthread_join( tid[i], NULL );
}
}
}
void *runner(void *arg)
{
size_t threadNum = (size_t)arg;
printf( "in thread: %zu\n", threadNum );
pthread_exit( NULL );
}
a run with no command line parameter results in: (where the executable is named: untitled
Usage: ./untitled <integer value>
a run with a command line parameter of 10 results in:
in thread: 0
in thread: 4
in thread: 2
in thread: 6
in thread: 1
in thread: 5
in thread: 7
in thread: 8
in thread: 9
in thread: 3
which makes it clear that threads are run in no particular order
1: I see no function called gettid()
pthread_t tid = gettid();
srand48(gettid());
2: You cannot print pthread_t as an integer, it's a structure
printf("My thread identifier is: %d\n", tid);
3: it's rand(), I have not seen nrand() before.
int max = nrand()%100;
Fix these and edit the question if required.
I'm working on an exercise (see bold text below) on semaphores and synchronization for my Operative System course. The text of the exercise is this:
Pthread semaphores and mutexes
The C program gen_binary_numbers.c receives on the command line an integer n, and uses recursion to generate and display all binary numbers of n bits.Transform the recursive program into a concurrent one, replacing the recursive procedure with the generation of an appropriate number of processes that display the binary numbers (in any order).
This is my code, actually:
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <pthread.h>
int num, r, c;
pthread_mutex_t mutex;
void *genBin(void *arg);
int main (int argc, char **argv) {
if (argc != 2) {
fprintf(stdout, "\nUSAGE: %s <n>\n\n", argv[0]);
exit(EXIT_FAILURE);
}
int i;
num = atoi(argv[1]);
c = num;
r = 2;
for (i=1; i<num; i++) {
r=r*2;
}
pthread_mutex_init(&mutex, NULL);
pthread_t* p;
p = malloc(r*sizeof(pthread_t));
for (i=0;i<r;i++) {
if (pthread_create(&p[i], NULL, genBin, &i)) {
fprintf(stderr, "Error creating thread.\n");
exit(EXIT_FAILURE);
}
}
pthread_exit(0);
}
void *genBin (void *arg) {
int x;
int i=0;
x = *((int*)arg);
pthread_mutex_lock(&mutex);
while (i<num) {
if(x!=0) {
fprintf(stdout, "%d", x%2);
}
else {
fprintf(stdout, "0");
}
i++;
x/=2;
}
fprintf(stdout, "\n");
pthread_mutex_unlock(&mutex);
pthread_exit(0);
}
I think that the code should return the right solution, but sometimes the output doesn't return the correct number.
Example of correct output:
./genBin 3
100
101
010
110
001
011
111
000
Example of wrong output (because of duplicates):
./genBin 3
110
110
110
001
011
111
111
000
I think that the problem is in the synchronization between the mutex and the printf.
Is there an alternative solution to avoid confusing results?
Your code contains a race condition. In main, you pass the address of your iteration variable, i, as the thread function's argument. Each new thread then races with the main thread to read the value of i (via the provided pointer) before the main thread increments it. One way you could address that problem would be to use a semaphore to make the main thread wait after creating each thread until that thread has dereferenced its argument.
Also, I don't think you need to use a mutex in genBin(). The only shared data it accesses is stdout, via fprintf(), and that function operates as if it locks an exclusive lock associated with the specified stream. Moreover, with the mutex you get essentially no actual concurrency because each thread holds the mutex locked for almost the complete duration of its execution.
The problem is in this part:
for (i=0;i<r;i++) {
if (pthread_create(&p[i], NULL, genBin, &i)) {
fprintf(stderr, "Error creating thread.\n");
exit(EXIT_FAILURE);
}
}
There's data race because you are passing the address of i to all threads. You could use an temp array to pass the individual number to each thread.
Thanks to everyone! You solved my problem. This is the corrected code:
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <pthread.h>
int num, r, c;
pthread_mutex_t mutex;
void *genBin(void *arg);
int main (int argc, char **argv) {
if (argc != 2) {
fprintf(stdout, "\nUSAGE: %s <n>\n\n", argv[0]);
exit(EXIT_FAILURE);
}
int i;
int *temp;
num = atoi(argv[1]);
c = num;
r = 2;
for (i=1; i<num; i++) {
r=r*2;
}
temp = malloc(r*sizeof(int));
pthread_mutex_init(&mutex, NULL);
pthread_t* p;
p = malloc(r*sizeof(pthread_t));
for (i=0;i<r;i++) {
temp[i] = i;
}
for (i=0;i<r;i++) {
if (pthread_create(&p[i], NULL, genBin, &temp[i])) {
fprintf(stderr, "Error creating thread.\n");
exit(EXIT_FAILURE);
}
}
for (i=0;i<r;i++) {
if (pthread_join(p[i], NULL)) {
fprintf(stderr, "Error creating thread.\n");
exit(EXIT_FAILURE);
}
}
pthread_mutex_destroy(&mutex);
free(temp);
free(p);
pthread_exit(0);
}
void *genBin (void *arg) {
int x;
int i=0;
int *v;
v = malloc(num*sizeof(int));
x = *((int*)arg);
for (i=0; i<num; i++) {
v[i] = x%2;
x/=2;
}
pthread_mutex_lock(&mutex);
for (i=0; i<num; i++) {
fprintf(stdout, "%d", v[i]);
}
fprintf(stdout, "\n");
pthread_mutex_unlock(&mutex);
free(v);
pthread_exit(0);
}
I wrote a program to learn about thread-specific data on Linux (Linux 3.13.0-24-generic #46-Ubuntu), as following.
I try to print thread id in the destructor function passed to pthread_key_create(), but it seems only sub threads succeed to print, but the main thread didn't print that info.
My question is:
Does the destructor function called right before or after termination of a thread?
The reason why main thread didn't print the info, is it due to the main thread already destroyed?
tsd_test.c
// test of thread-specific data
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
static pthread_once_t once = PTHREAD_ONCE_INIT;
static pthread_key_t tidKey;
static void destructor(void *buf) {
unsigned long *_tid = buf;
printf("destroy, tid: %lu\n", *_tid);
free(buf);
}
static void createKey(void) {
int s = pthread_key_create(&tidKey, destructor);
if(s != 0) {
printf("failed to create key\n");
exit(-1);
}
}
void *store_tid() {
int s;
unsigned long *buf;
// create key
s = pthread_once(&once, createKey);
if(s != 0) {
printf("failed to create key\n");
exit(-1);
}
buf = pthread_getspecific(tidKey);
if(buf == NULL) { // thread call this function for the first time,
buf = malloc(sizeof(unsigned long));
if(buf == NULL) {
printf("failed to allocate memory, %s\n", strerror(errno));
exit(-1);
}
// register buffer to specified key & current thread,
s = pthread_setspecific(tidKey, buf);
if(s != 0) {
printf("failed to setspecific\n");
exit(-1);
}
}
// store tid to buffer,
*buf = (unsigned long)pthread_self();
printf("set tid to: %lu\n", *buf);
return buf;
}
void tsd_test() {
unsigned long *tidp_a = store_tid();
printf("tid - before call another thread: %lu\n", *tidp_a);
int s;
pthread_t t2;
s = pthread_create(&t2, NULL, &store_tid, NULL);
if(s != 0) {
printf("failed to create thread\n");
exit(-1);
}
s = pthread_join(t2, NULL);
if(s != 0) {
printf("failed to join thread\n");
exit(-1);
}
printf("tid - after call another thread: %lu\n", *tidp_a);
}
int main(int argc, char *argv[]) {
tsd_test();
return 0;
}
Compile:
gcc -pthread tsd_test.c
Output:
set tid to: 3076318976
tid - before call another thread: 3076318976
set tid to: 3076315968
destroy, tid: 3076315968
tid - after call another thread: 3076318976
You can see that only the sub thread print "destroy", while the main thread didn't.
The thread destructor is called when the thread exits, not when the process dies i.e. when main() exits, the entire process dies. So destructor will not be called on that.
Call pthread_exit(NULL); either at the end of main() function or at the end tst() function (both are same really). Now, you will see the destructor being called.