Program won't execute pthread - c

I have to design a multi-threaded application involved with the consumer-producer problem. So far, I've been trying to get the Pthreads to work correctly before I try to implement my solution. But, my program won't even load up the the function on my pthread. I'm not sure what I'm doing wrong here.
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
void* Producer(void *arg)
{
printf("\nEntered Producer\n");
int i, item, index;
index = (int)arg;
FILE *f = fopen(bookorders, "r");
char c = fgetc(f);
int z =0;
while (c!=EOF) {
char * buffer = (char *)malloc(1000);
while (c!='\n') {
*(buffer+z) = c;
z++;
c = fgetc(f);
}
char delim[2] = "|";
printf("%s\n", buffer);
}
}
int main(int argc, const char * argv[])
{
pthread_t Produc;
pthread_create(&Produc, NULL, Producer, NULL);
return 0;
}
I guess my big question is what is the proper process of creating a pthread and then getting it to run a function, which in this case is my Producer function

What's happening here is your main thread calls pthread_create and just returns and since the main thread exits, your Production thread also exits. What you need to do is, instruct the main thread to wait for the Produc thread to finish executing.
int main(){
//Call pthread_create
pthread_join(Produc, NULL) ;
return 0;
}

Related

Trying to create a multi threaded C program that prints a string in reverse order

I am working on an assignment for my C coding class that requires us to create multiple threads that run different functions. As to ease my confusion, I am trying to do the program one thread at a time, but I am having some trouble. Here is my code:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
void * print_string_in_reverse_order(void *str)
{
// This function is called when the new thread is created
printf("%s","In funciton start_routine(). Your string will be printed backwards.");
char *word[50];
strcpy (*word, (char *)str);
int length = strlen(*word);
for (int x = length-1; x >= 0; x--){
printf("%c",&word[x] );
}
pthread_exit(NULL); // exit the thread
}
int main(int argc, char *argv[])
{
/* The main program creates a new thread and then exits. */
pthread_t threadID;
int status;
char input[50];
printf("Enter a string: ");
scanf("%s", input);
printf("In function main(): Creating a new thread\n");
// create a new thread in the calling process
// a function name represents the address of the function
status = pthread_create(&threadID, NULL, print_string_in_reverse_order, (void *)&input);
// After the new thread finish execution
printf("In function main(): The new thread ID = %d\n", threadID);
if (status != 0) {
printf("Oops. pthread create returned error code %d\n", status);
exit(-1);
}
printf("\n");
exit(0);
}
At present, while I have no compiler errors, it does not print anything and does not appear to reverse the string in any way. I am very new to C so I assume it is something like errors with my pointers, but even after several changes and attempts I can't seem to figure out what's wrong. Does anyone have an idea?
If word is supposed to be a char array holding a string, the line
char *word[50];
should be changed to:
char word[50];
Also, the line
strcpy (*word, (char *)str);
should be changed to:
strcpy (word, (char *)str);
In additon, the line
printf("%c",&word[x] );
should be changed to:
printf("%c", word[x] );
Also, before returning from function main(), you must wait for the created thread to finish executing, by adding the following line:
pthread_join( threadID, NULL );
Otherwise, your thread may be terminated prematurely.

Bounded buffer sharing with Pthread and mutex locks busy waiting

I am trying to create a producer consumer queue, using mutex locks, creating busy waiting between threads. My Main file takes X amount of integer arguments, pushes them onto a BOUNDED BUFFER of size 50. I am using a while loop to do this since you do not know the amount before hand. I am not sure when and where to create my producer thread.
NOTE: Main is a "producer" in the sense it fills the buffer, but my actual producer function is going to pass onto my consumer function later in my code, so disregard the names. Main is going to "Produce" numbers by pushing and producer is going to pop those numbers for later use. My question is where and when do I make my Pthread_create in my code for producer and am I using the Mutex locks correctly to have synchronization between the two threads?
#include <pthread.h>
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#define BUFFER_SIZE (50)
typedef struct {
int buffer[BUFFER_SIZE];
int count;
int top;
int next;
pthread_mutex_t count_lock;
} prodcons;
void pc_init(prodcons *pc);
int pc_pop(prodcons *pc);
void pc_push(prodcons *pc, int val);
void factor2pc(prodcons *pc, int number);
void *producer(void *data);
void *consumer(void *data);
int main(int argc, char *argv[])
{
int index = 1;
int num;
prodcons pc_nums;
//pthread_t tid[argc - 1];
pthread_t tid;
pthread_attr_t attr;
if (argc < 2) {
fprintf(stderr, "usage: No arguments\n");
return -1;
}
if (atoi(argv[1]) <= 0)
{
fprintf(stderr, "%d not > 0 or you must provide a positive integer.\n", atoi(argv[1]));
return -1;
}
pthread_attr_init(&attr);
pc_init(&pc_nums);
//DO I PUT THIS HERE or WHILE LOOP?
pthread_create(&tid, &attr, *producer, &pc_nums);
while (index < argc)
{
num = atoi(argv[index]);
pc_push(&pc_nums, num);
index++;
}
}
void *producer(void *data)
{
prodcons *dataStruct = data;
while (dataStruct->count < BUFFER_SIZE)
{
number = pc_pop(data);
//This print is just here to make sure I am correctly "poping" from buffer
printf("%d\n", number);
}
}
void pc_init(prodcons *pc)
{
pc->count = 0;
pc->top = 0;
pc->next = 0;
if (pthread_mutex_init(&pc->count_lock, NULL) != 0)
{
printf("\n mutex init has failed\n");
}
}
int pc_pop(prodcons *pc)
{
int val;
pthread_mutex_lock(&pc->count_lock);
if (pc->count > pc->top)
{
val = pc->buffer[pc->count];
printf("%d\n", val);
pc->buffer[pc->count] = 0;
pc->count--;
}
pthread_mutex_unlock(&pc->count_lock);
return val;
}
void pc_push(prodcons *pc, int val)
{
pthread_mutex_lock(&pc->count_lock);
if (pc->count < BUFFER_SIZE)
{
pc->buffer[pc->count] = val;
pc->count++;
}
pthread_mutex_unlock(&pc->count_lock);
}
My question is where and when do I make my Pthread_create in my code for producer and am I using the Mutex locks correctly to have synchronization between the two threads?
As long as all is properly initialized and synchronized, you can put the pthread_create() call wherever you want, including where it's placed in the given program. But at least two things are wrong:
pc_pop() behaves undefined (by return of an uninitialized value) if there is no number in the buffer to pop.
Since dataStruct->count is accessed by producer() without locking, the declaration should be _Atomic(int) count;.

How can I have a shared counter in multithreading using structs?

I'm pretty new with multithreading and I was trying to increment a shared counter whithout using global variables, my goal is try to maximize the concurrency among the different threads and increment the variable until a number I give in arguments... Sorry if is a lame question, but I would like a help here, when I compile my code and run it i get a segmentation fault... I think the error is in the variable count that I create and the shared counter!
#include <stdio.h>
#include <pthread.h>
pthread_mutex_t mutex;
typedef struct {
long *cnt; /* pointer to shared counter */
long n; /* no of times to increment */
int nr;
pthread_t id; /* application-specific thread-id */
} targ_t;
void *sfun(void *arg) {
targ_t *est = (targ_t *) arg;
here:
pthread_mutex_lock(&mutex);
(*(est->cnt))++;
pthread_mutex_unlock(&mutex);
if(*(est->cnt)<est->n)
goto here;
return NULL;
}
int main(int argc, char *argv[]){
targ_t real[3];
int c=0;
long count=0;
real[0].cnt=&count;
pthread_mutex_init(&mutex, NULL);
for(c=0;c<3;c++){
real[c].n=atoi(argv[1]);
real[c].nr=c+1;
pthread_create(&real[c].id,NULL,&sfun,&real[c]);
}
for(c=0;c<3;c++){
pthread_join(real[c].id,NULL);
}
pthread_mutex_destroy(&mutex);
printf("OVERALL %lu\n", count);
return 0;
}
TY in advance.
There are a number of problems identified in the comments:
Writing out loops with a label here: and a goto here; is not a particularly good idea. There are occasions (some, but not many, occasions) when it is appropriate to use goto — this is not one of those rare occasions.
You don't actually validate that your code was given an argv[1] to convert; could it be that you forgot to pass that argument?
However, your primary problem is that you initialize real[0].cnt but you do not initialize real[1].cnt or real[2].cnt, so those threads are accessing who knows what memory — it might be that they're using null pointers, or they might be pointers to anywhere in memory, allocated or not, aligned or not, writable or not.
You're also missing <stdlib.h>
You're testing *(est->cnt) outside the scope of mutual exclusion.
This code fixes those and some other issues:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
typedef struct
{
long *cnt; /* pointer to shared counter */
long n; /* no of times to increment */
int nr;
pthread_t id; /* application-specific thread-id */
} targ_t;
static void *sfun(void *arg)
{
targ_t *est = (targ_t *)arg;
while (1)
{
pthread_mutex_lock(&mutex);
long cval = *est->cnt;
if (cval < est->n)
++*est->cnt;
pthread_mutex_unlock(&mutex);
if (cval >= est->n)
break;
}
return NULL;
}
int main(int argc, char *argv[])
{
targ_t real[3];
long count = 0;
if (argc != 2)
{
fprintf(stderr, "Usage: %s count\n", argv[0]);
return(EXIT_FAILURE);
}
for (int c = 0; c < 3; c++)
{
real[c].cnt = &count;
real[c].n = atoi(argv[1]);
real[c].nr = c + 1;
if (pthread_create(&real[c].id, NULL, &sfun, &real[c]) != 0)
break;
}
for (int c = 0; c < 3; c++)
pthread_join(real[c].id, NULL);
pthread_mutex_destroy(&mutex);
printf("OVERALL %lu\n", count);
return 0;
}
When run (for example, the program is pth59):
$ pth59 100
OVERALL 100
$
Before moving the test (now on cval) so that the read of *est->cnt was done inside the scope of the mutex, I got an output OVERALL 102 from the same command line. It is important to access shared variables with proper mutual exclusion, even if it is read-only access.

segmentation fault in multithreading program

I'm trying to multiply two matrices using multithreading. But the code is giving segmentation fault. I am passing the row number and column number using a structure. The matrices a and b are made global. This is not entirely correct way to do it, but I'm just trying to understand how multithreading stuff works.
#include <pthread.h>
#include <unistd.h>
#include <iostream>
using namespace std;
int a[3][3]={{1,2,3},{4,5,6},{7,8,9}};
int b[3][2]={{1,2},{3,4},{5,6}};
int c[3][2];
int k =3;
struct thread_data{
int m;
int n;
};
void* do_loop(void* threadarg)
{
int p,q;
struct thread_data *my_data;
my_data = (struct thread_data *) threadarg;
int i=my_data->m;
int j=my_data->n;
c[i][j]=0;
for(q=0;q<k;q++)
{
c[i][j]=c[i][j]+a[i][q]*b[q][j];
}
pthread_exit(NULL);
}
int main(int argc, char* argv[])
{
int i,j,k;
struct thread_data td[6];
int thr_id;
pthread_t p_thread[6];
int count=0;
for(i=0;i<3;i++)
for(j=0;j<2;j++)
{
td[count].m=i;
td[count].n=j;
thr_id = pthread_create(&p_thread[count], NULL, do_loop, (void*)&td[count]);
// pthread_join(p_thread[count],NULL);
count++;
}
return 0;
}
How can I fix the segmentation fault?
First thing, you need to wait for all the threads to finish (in main):
for (i = 0; i < count; ++i) {
pthread_join(p_thread[i],NULL);
}
Failure to do so will crash your app as the thread continue to work why the application is being destroyed.
You need to call pthread_join after you create all the threads.
If you create a thread and immediately call pthread_join you execution is serial as one thread is active at any given time.
Explanation:
"join" means: "wait for thread to finish execution". A thread finishes execution when either it returns from it's entry point function (function passed to pthread_create) or it calls pthread_exit.

Thread struct as function parameter C

I'm having a trouble passing a struct pointer into a function because I'm a bit confused with those pointers and references. I want to modify the thread.thread_num value from the thread_startfunction.
#include <stdio.h>
#include <stdlib.h> //malloc, free
#include <pthread.h>
#define N 5
// void *malloc(size_t);
struct thread {
pthread_t thread_id;
int thread_num;
// int thread_sum;
};
void *thread_start(void *thread)
{
struct thread *my_data;
my_data = (struct thread *)thread;
printf("num T: %i\n", my_data->thread_num);
my_data->thread_num=4;
printf("num T: %i\n", my_data->thread_num);
return NULL;
}
int main(int argc, char *argv[])
{
int i;
struct thread pthread_data;
struct thread *thread = &pthread_data;
thread->thread_num=2;
pthread_create(&thread->thread_id, NULL, thread_start, (void *)&thread);
printf("num: %i\n",thread->thread_num);
pthread_exit(NULL);
return 0;
}
But the value that print the main doesn't change (2).
And then I want to create an array of thread struct, but I don't know how exactly do that:
I guess it should be something like this:
int main(int argc, char *argv[])
{
int i;
struct thread pthread_data;
struct thread *thread[N-1] = &pthread_data; // I don't know how to manage this.
for(i=0; i<N; i++)
{
thread->thread_num=i;
pthread_create(&thread[i]->thread_id, NULL, thread_start, (void *)&thread[i]);
printf("num %i: %i\n",i,thread[i]->thread_num);
}
pthread_exit(NULL);
return 0;
}
Any thoughts?
I recommend you to read http://www.advancedlinuxprogramming.com/alp-folder/alp-ch04-threads.pdf
And here what you wanted:
#define N 5
typedef struct thread {
pthread_t thread_id;
int thread_num;
// int thread_sum;
} ThreadData;
void *thread_start(void *thread)
{
ThreadData *my_data = (ThreadData*)thread;
//there is no guarantee that prints will be in order
// we will use its initial thread->num ,cause it differs for each thread
//plus you will see how threads will behave
int order=my_data->thread_num;
printf("%i) before num T: %i\n",order, my_data->thread_num);
my_data->thread_num=4;
printf("%i) after assignment num T: %i\n",order ,my_data->thread_num);
return NULL;
}
int main(int argc, char *argv[])
{
int i;
ThreadData thread[N];
for(i=0; i<N; i++)
{
thread[i].thread_num=i;
pthread_create(&(thread[i].thread_id), NULL, thread_start, (void *)(thread+i));
}
//wait for all threads
for (i = 0; i < N; i++)
pthread_join(thread[i].thread_id, NULL);
//print results of each thread
for (i = 0; i < N; i++)
printf(" %i)thread: number %i\n",i,thread[i].thread_num);
return 0;
}
I can see multiple mistakes in your code.
First you have your pointers wrong. In the first example, it is enough to pass &pthread_data to pthread_create, &thread is the address of the thread pointer, so you are passing struct thread ** to your function instead of struct thread *. In the second example you should use (void *) thread[i]. &thread[i] is again struct thread **.
When you want each thread to write to its own thread data, then you should make an array of thread data, so that each thread has its own piece, else you will run into race conditions.
As others have already pointed out, you should call pthread_join before calling printf to ensure that the main thread will wait for all worker threads.
Also note that if you are calling pthread_join from other function that the one that spawned those threads, you have to ensure that the array of tread data will not go out of scope (in this case it would be probably better to use malloc or a global array).
You can't. As soon as main exits, which it does when you call pthread_exit, pthread_data ceases to exist, since it's local to the main function. So it can't be modified.

Resources