I am trying to create a thread and from what I remember this should be the right way to do it:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 5
int SharedVariable =0;
void SimpleThread(int which)
{
int num,val;
for(num=0; num<20; num++){
if(random() > RAND_MAX / 2)
usleep(10);
val = SharedVariable;
printf("*** thread %d sees value %d\n", which, val);
SharedVariable = val+1;
}
val=SharedVariable;
printf("Thread %d sees final value %d\n", which, val);
}
int main (int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
long t;
for(t=0; t< NUM_THREADS; t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, SimpleThread, (void* )t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
/* Last thing that main() should do */
pthread_exit(NULL);
}
And the error that I'm getting is this one:
test.c: In function ‘main’: test.c:28: warning: passing argument 3 of
‘pthread_create’ from incompatible pointer type
/usr/include/pthread.h:227: note: expected ‘void * (*)(void *)’ but
argument is of type ‘void (*)(int)’
I cannot change the SimpleThread function so changing the type of the parameter is not an option even though I already tried and it didn't work either.
What am I doing wrong?
SimpleThread should be declared as
void* SimpleThread(void *args) {
}
When you pass parameters to your thread, it is best to define a struct for them, pass a pointer to that struct as void*, and cast back to the right type inside the function.
Here's a compiling and "working" version of your program, although I have to admit to not knowing exactly what it's doing. For the critics in the audience, I apologize in advance for the pthread_join loop at the end.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define NUM_THREADS 5
struct my_thread_info {
long which;
};
int SharedVariable = 0;
void *SimpleThread(void *data)
{
int num, val;
struct my_thread_info *info = data;
for (num = 0; num < 20; num++) {
if (random() > RAND_MAX / 2)
usleep(10);
val = SharedVariable;
printf("*** thread %ld sees value %d\n", info->which, val);
SharedVariable = val + 1;
}
val = SharedVariable;
printf("Thread %ld sees final value %d\n", info->which, val);
free(info);
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
long t;
struct my_thread_info *info;
for (t = 0; t < NUM_THREADS; t++) {
printf("In main: creating thread %ld\n", t);
info = malloc(sizeof(struct my_thread_info));
info->which = t;
rc = pthread_create(&threads[t], NULL, SimpleThread, info);
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], NULL);
}
}
Related
I need to create two private keys and two threads and then I need to make these threads "exchange" keys
I already created the keys and initialized them and I can also print their value, but I do not know how to make them exchange keys. Maybe someone will tell you something. maybe for this I need to call the same thread several times, but I also don’t know how to do this. I do not ask you to give me a ready-made program, maybe just some little hint or advice
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
pthread_key_t key, key2;
void get_data()
{
int *x = (int*)pthread_getspecific(key2);
if(x == NULL)
printf("The value is NULL\n");
else
printf("Key value is %d\n", *x);
}
void get_data2()
{
int *x = (int*)pthread_getspecific(key);
if(x == NULL)
printf("The value is NULL\n");
else
printf("Key value is %d\n", *x);
}
void *func(void *data)
{
int *num;
int *x;
printf("Thread №%ld\n", pthread_self());
num = (int*)data;
get_data();
pthread_setspecific(key, (void*)num);
get_data();
}
void *func2(void *data)
{
int *num;
int *x;
printf("Thread №%ld\n", pthread_self());
num = (int*)data;
get_data2();
pthread_setspecific(key2, (void*)num);
get_data2();
}
int main()
{
int ret_code, type = 3;
pthread_t th, th2;
ret_code = pthread_key_create(&key, NULL);
if(ret_code != 0)
fprintf(stderr, "ptrhead_key_create() error %d\n", ret_code);
ret_code = pthread_key_create(&key2, NULL);
if(ret_code != 0)
fprintf(stderr, "ptrhead_key_create() error %d\n", ret_code);
printf("type: %d\n", type);
ret_code = pthread_create(&th, NULL, func, (void*)&type);
if(ret_code != 0)
fprintf(stderr, "pthread_create() error %d\n", ret_code);
sleep(1);
type = 10;
printf("type: %d\n", type);
ret_code = pthread_create(&th2, NULL, func2, (void*)&type);
if(ret_code != 0)
fprintf(stderr, "pthread_create() error %d\n", ret_code);
ret_code = pthread_join(th, NULL);
ret_code = pthread_join(th2, NULL);
}
The Idea here is to create a file to be written to. I'm trying to create ten threads and have them print to the file 10 times each. Using a semaphore to stop multiple threads from writing to the file at once. But I have errors. The code is below:
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#define FNAME "fisier.txt"
#define MAX_STRING_LEN 80
#define NUMBER_OF_THREADS 10
FILE *fp;
sem_t mutex;
int counter;
FILE *makeTextFile(char *fname, char mode){
FILE *localFP;
localFP = fopen(fname, &mode);
return (localFP);
}
void *print_message(void *tid){
int i;
for (i = 0; i < 10; i++){
sem_wait(&mutex);
fp = fopen(FNAME, "a");
fprintf(fp, "Thread %d is running.\n", tid);
fclose(fp);
sem_post(&mutex);
printf ( "Thread %d has finished.\n", tid);
}
}
int threads(){
const char *fName = "fisier.txt";
int status;
pthread_t threads[NUMBER_OF_THREADS];
fp = makeTextFile(FNAME, 'w');
fprintf(fp, "Process ID: %ld\n", (long)getpid());
fclose(fp);
int i;
for (i =0; i < NUMBER_OF_THREADS; i++){
status = pthread_create(&threads[i], NULL, &print_message, (void *)i);
if (status != 0){
printf("pthread_create returned error code %d\n", status);
exit(-1);
}
}
}
int main() {
threads();
return 0;
}
Warnings:
probl2.c: In function ‘print_message’:
probl2.c:27:21: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘void *’ [-Wformat=]
fprintf(fp, "Thread %d is running.\n", tid);
^
probl2.c:30:14: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘void *’ [-Wformat=]
printf ( "Thread %d has finished.\n", tid);
^
probl2.c: In function ‘threads’:
probl2.c:44:68: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
status = pthread_create(&threads[i], NULL, &print_message, (void *)i);
Writing in a file just it: Process ID: 10568
I want to write
How to solve it ?
A couple of things I noticed:
You are not initializing your semaphore. Use sem_init to do this (and use sem_destroy when you are finished).
You are not joining on your threads. The program will exit without waiting for the threads to finish. You can use pthread_join in a loop to make sure all threads have finished.
Here is an updated version of your threads function. In production code I would check the return values of the functions I added.
void threads(){
const char *fName = "fisier.txt";
int status;
pthread_t threads[NUMBER_OF_THREADS];
fp = makeTextFile(FNAME, 'w');
fprintf(fp, "Process ID: %ld\n", (long)getpid());
fclose(fp);
sem_init(&mutex,0,1);
int i;
for (i =0; i < NUMBER_OF_THREADS; i++){
status = pthread_create(&threads[i], NULL, &print_message, (void*)i);
if (status != 0){
printf("pthread_create returned error code %d\n", status);
exit(-1);
}
}
void* value = NULL;
for (i = 0; i < NUMBER_OF_THREADS; i++) {
pthread_join(threads[i], &value);
}
sem_destroy(&mutex);
}
I keep getting a seg fault (core dump) after pthread_join in my program. It prints out the expected result just fine, but seg faults when joining the thread. I have looked at several other discussions on this topic, but none of the suggested solutions seem to work in my case. Here is what my compile command looks like (no compile warnings or errors):
$ gcc -Wall -pthread test.c -o test
Here is the output:
$ ./test
1 2 3 4 5 6 7 8 9 10
Segmentation fault (core dumped)
And here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int array[10];
void *fillArray(int *size) {
int i;
for (i = 0; i < *size; i++) {
array[i] = i+1;
}
return NULL;
}
int main (int argc, char *argv[])
{
int i, rc;
int size = 10;
pthread_t thread;
void *res, *end;
//initialize the array
for (i = 0; i < size; i++) {
array[i] = 0;
}
rc = pthread_create(&thread, NULL, fillArray(&size), &res);
if (rc != 0) {
perror("Cannot create thread");
exit(EXIT_FAILURE);
}
//print the array
for (i = 0; i < size; i++) {
if (array[i] != -1)
printf("%d ", array[i]);
}
printf("\n");
rc = pthread_join(thread, &end);
if (rc != 0) {
perror("Cannot join thread");
exit(EXIT_FAILURE);
}
return 0;
}
Any ideas what could be the cause?
This doesn't compile for me: It fails with
dummy.cpp: In function ‘int main(int, char**)’:
dummy.cpp:29: error: invalid conversion from ‘void*’ to ‘void* (*)(void*)’
dummy.cpp:29: error: initializing argument 3 of ‘int pthread_create(_opaque_pthread_t**, const pthread_attr_t*, void* (*)(void*), void*)’
Which is because you're actually calling fillArray and passing its result to pthread_create, rather than passing the function pointer. I expect your code will need to look more like this (UNTESTED!) : (Note I changed signature of fillArray, created data struct type to pass to fillArray, changed how pthread_create is called)
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int array[10];
struct fillArrayData {
int * array;
int size;
int * result;
};
void *fillArray(void *void_data) {
fillArrayData * data = (fillArray*)void_data;
for (int i = 0; i < data.size; i++) {
data.array[i] = i+1;
}
//You could fill in some return info into data.result here if you wanted.
return NULL;
}
int main (int argc, char *argv[])
{
int i, rc;
int size = 10;
pthread_t thread;
void *res, *end;
//initialize the array
for (i = 0; i < size; i++) {
array[i] = 0;
}
fillArrayData data;
data.array = array;
data.size = 10;
rc = pthread_create(&thread, NULL, fillArray, &data);
if (rc != 0) {
perror("Cannot create thread");
exit(EXIT_FAILURE);
}
//print the array
for (i = 0; i < size; i++) {
if (array[i] != -1)
printf("%d ", array[i]);
}
printf("\n");
rc = pthread_join(thread, &end);
if (rc != 0) {
perror("Cannot join thread");
exit(EXIT_FAILURE);
}
return 0;
}
Error in
Calling function pointer
passing parameter to thread handler
In pthread prototype of pthread_create below
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
1st argument - pthread_variable
2nd argument - thread attrubutes
3rd argument - thread handler(function pointer name)
4th argument - variable need to pass thread handler.
In 4th argument - if two thread want to share single variable, then create global variable, and the pass this variable when creating thread.
sample program:
#include <pthread.h>
#include <stdio.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];
int rc;
long t;
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);
}
}
pthread_exit(NULL);
}
further details here
I am trying to use pthread mutex variables and barrier to synchronize the output of my program, but it is not working the way I want it to. Each thread is seeing its final value every 20 values (coming from the for loop) which is alright but I'm trying to make them all get to the same final value (if using 5 threads, all of them should see 100 as final value, with 4 threads, 80, etc)
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
int SharedVariable =0;
void *SimpleThread(void *args)
{
int num,val,rc;
int which =(int)args;
rc = pthread_mutex_lock(&mutex1);
for(num=0; num<20; num++){
#ifdef PTHREAD_SYNC
if(random() > RAND_MAX / 2)
usleep(10);
#endif
//pthread_mutex_lock(&mutex1);
val = SharedVariable;
printf("*** thread %d sees value %d\n", which, val);
//pthread_mutex_lock(&mutex1);
SharedVariable = val+1;
pthread_mutex_unlock(&mutex1);
}
val=SharedVariable;
printf("Thread %d sees final value %d\n", which, val);
//pthread_mutex_destroy(&mutex1);
//pthread_exit((void*) 0);
//pthread_mutex_unlock(&mutex1);
}
int main (int argc, char *argv[])
{
if(atoi(argv[1]) > 0){
int num_threads = atoi(argv[1]);
//pthread_mutex_init(&mutex1, NULL);
pthread_t threads[num_threads];
int rc;
long t;
rc = pthread_mutex_lock(&mutex1);
for(t=0; t< num_threads; t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, SimpleThread, (void* )t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
//pthread_join(thread1);
}
rc= pthread_mutex_unlock(&mutex1);
}
else{
printf("ERROR: The parameter should be a valid positive number.");
exit(-1);
}
pthread_mutex_destroy(&mutex1);
pthread_exit(NULL);
}
Any suggestions or help is greatly appreciated!
Thanks in advanced!
You need to use a barrier (pthread_barrier_wait()) before checking for the final value - this ensures that no thread will proceed until all threads have reached the barrier.
In addition, you should be calling pthread_join() to wait for the threads to finish, and you only need to hold the mutex around the increment:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_barrier_t barrier1;
int SharedVariable = 0;
void *SimpleThread(void *args)
{
int num,val;
int which = (int)args;
for(num = 0; num < 20; num++) {
#ifdef PTHREAD_SYNC
if(random() > RAND_MAX / 2)
usleep(10);
#endif
pthread_mutex_lock(&mutex1);
val = SharedVariable;
printf("*** thread %d sees value %d\n", which, val);
SharedVariable = val + 1;
pthread_mutex_unlock(&mutex1);
}
pthread_barrier_wait(&barrier1);
val = SharedVariable;
printf("Thread %d sees final value %d\n", which, val);
return 0;
}
int main (int argc, char *argv[])
{
int num_threads = argc > 1 ? atoi(argv[1]) : 0;
if (num_threads > 0) {
pthread_t threads[num_threads];
int rc;
long t;
rc = pthread_barrier_init(&barrier1, NULL, num_threads);
if (rc) {
fprintf(stderr, "pthread_barrier_init: %s\n", strerror(rc));
exit(1);
}
for (t = 0; t < num_threads; t++) {
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, SimpleThread, (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], NULL);
}
}
else {
printf("ERROR: The parameter should be a valid positive number.\n");
exit(-1);
}
return 0;
}
Try to move the pthread_mutext_unlock(&mutext1) out of the for loop in your SimpleThread. You lock once and unlock mutiple(20) times in your original code.
Alternatively, you could move pthread_mutex_lock(&mutext1) into the for loop, just before you read and modify your SharedVariable. In this case, each thread's add-by-one operation may not consecutive but each thread will get the correct final value.
And before you read the final value of the SharedVariable, use a barrier to wait all the threads finish their job.
I am using an old exam as a study guide and one of the questions is to use pthreads to fill in the following code:
#include <pthread.h>
#include <stdio.h>
typedef struct {
int a;
int b;
} local_data;
void *foo(void *arg);
int main() {
int a = 12;
int b = 9;
pthread_t tid;
pthread_attr_t attr;
local_data local;
local.a = a;
local.b = b;
pthread_attr_init(&attr);
/* block of code we are supposed to fill in (my attempt at filling it in)
pthread_create(&tid, &attr, foo, &local);
pthread_join(tid, NULL);
*/
b = b - 5;
printf("program exit. a = %d, b = %d\n", a, b);
return 0;
}
void *foo(void *arg) {
int a, b;
local_data *local = (local_data*)arg;
/* block of code we are supposed to fill in (my attempt at filling it in)
a = local->a;
b = local->b;
a++;
*/
printf("program exit. a = %d, b = %d\n", a, b);
pthread_exit(0);
}
What we are supposed to do is make our pthreads mimic this code:
int main() {
int a = 12;
int b = 9;
int fid = fork();
if (fid == 0) {
a++;
}
else {
wait(NULL);
b = b - 5;
}
printf("program exit. a = %d, b = %d\n", a, b);
return 0;
}
I've been really lost on this section and I am sure I do not understand it as well as I should (or at all). Would appreciate any answers to help me grasp the concept.
This line is wrong:
pthread_create(&tid, &attr, foo(local), NULL);
pthread_create's signature is:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void*), void *arg);
The third argument is a function and the last argument is it's argument, so instead of calling the function (foo(local)), pass the function and the argument separately:
pthread_create(&tid, &attr, foo, &local);