I made this little program to understand pthreads a bit more. I tried to compute the powers of 0-99 over 10 threads. It works fine without pthread_join or when I join only the first 4 threads. Joining anything above 4 segfaults the program. What is the reason my program segfaults when I am joining more than the first 4 threads.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <pthread.h>
#define NUM_THREADS 10
double *powr;
void *pows(void *arg){
int n = *((int*)arg)*10;
for(int i = n; i < n+10; i++){
powr[i] = pow(i, 2);
}
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t thread_ID[NUM_THREADS];
void *exit_status[NUM_THREADS];
int rank[NUM_THREADS], j;
powr = (double *)malloc(NUM_THREADS*10);
for(j = 0; j < NUM_THREADS; j++){
rank[j] = j;
pthread_create(&thread_ID[j], NULL, pows, &rank[j]);
}
for(j = 0; j < NUM_THREADS; j++){
pthread_join(thread_ID[j], NULL);
}
for(j = 0; j < NUM_THREADS*10; j++){
printf("%.0lf ", powr[j]);
}
return 0;
}
after changing malloc(NUM_THREADS*10); to malloc(NUM_THREADS*10*sizeof(double)); it runs correctly.
Related
I'm trying to write a code that prints "Hello World!" 10 times with "sleep" for a second, then the program should print "Hello Moon!" 10 times with "sleep" for 0.2 seconds. This process must be repeated forever. The problem is that the program only prints "Hello World!" 10 times. I do not really understand how to get the next thread to run!
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "wrapper.h"
#include <pthread.h>
#define MAX 10
void* HelloMoonFunction(void* tid){
long t_id;
t_id = (long)tid;
sleep(tid);
printf("%d. Hello Moon! \n", tid+1);
return NULL;
}
void* HelloWorldFunction(void* tid){
int value = (int) (intptr_t) tid;
sleep(value);
printf("%d. Hello World!\n", value + 1);
return NULL;
}
int main(int ac, char * argv){
pthread_t hej,moon;
while(1){
for (int a = 0; a < MAX; a++){
pthread_create(&hej, NULL, HelloWorldFunction, (void*)(intptr_t) a);
}
for (int b = 0; b < MAX; b++){
pthread_join(&hej, NULL);
}
for (int i = 0; i < MAX; i++){
pthread_create(&moon, NULL, HelloMoonFunction, (void*)(intptr_t) i);
}
for (int j = 0; j < MAX; j++){
pthread_join(moon, NULL);
}
}
pthread_exit(NULL);
return(0);
}
The most important issue in your code is that the 10 thread IDs are stored in the same variable so the 10 pthread_joins are all called for the last thread ID.
Secondly, the data passed to the thread functions is an integer encoded into a pointer. This is not guaranteed to go well. A more portable approach would be to save the argument and pass a pointer to the saved value. However, your approach does simplify the code, so I have kept it below. Just be warned.
The 0.2 seconds difference in sleep times that you would like in the HelloMoonFunction() cannot be accomplished with sleep (sleep for n seconds), but the Posix usleep (sleep for n microseconds) is probably available even though it is obsoleted by Posix.
A modified version doing what I understand you want to accomplish could be the following:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#define MAX 10
void* HelloMoonFunction(void* tid){
int value = (intptr_t)tid;
usleep(value*200000);
printf("%d. Hello Moon! \n", value+1);
return NULL;
}
void* HelloWorldFunction(void* tid){
int value = (intptr_t)tid;
usleep(value*1000000);
printf("%d. Hello World!\n", value + 1);
return NULL;
}
int main(void){
pthread_t hej[MAX], moon[MAX];
while(1){
for (int a = 0; a < MAX; a++){
pthread_create(&hej[a], NULL, HelloWorldFunction, (void *)(intptr_t)a);
}
for (int b = 0; b < MAX; b++){
pthread_join(hej[b], NULL);
}
for (int i = 0; i < MAX; i++){
pthread_create(&moon[i], NULL, HelloMoonFunction, (void *)(intptr_t)i);
}
for (int j = 0; j < MAX; j++){
pthread_join(moon[j], NULL);
}
}
return(0);
}
#include <stdio.h>
#include <pthread.h>
void *runner(void * p)
{
int *line = p;
printf("line: %d\n", *line);
}
int main()
{
pthread_t tid[2];
for (int i = 0; i < 2; i++)
pthread_create(&tid[i], 0, runner, &i);
for (int i = 0; i < 2; i++)
pthread_join(tid[i], NULL);
return 0;
}
For the above code I expect the output to be
line 0
line 1
But the output is actually
line 1
line 2
So what is wrong with this code? How did i get incremented? Do I have to pass structs to the runner function?
There's no guarantee that printf("line: %d\n", *line); line will finish before pthread_create returns, which means you have a race on i.
(The main thread tries to increment it and the new threads try to read it
via their argument pointer).
You can solve the problem by passing pointers to different objects (one per thread, optimally cache-aligned, but that hardly matters here):
#include <stdio.h>
#include <pthread.h>
void *runner(void * p)
{
int *line = p;
printf("line: %d\n", *line);
return 0;
}
int main()
{
pthread_t tid[2];
int ints[2];
for (int i = 0; i < 2; i++){
ints[i]=i;
if(pthread_create(&tid[i], 0, runner, &ints[i])) return 1;
}
for (int i = 0; i < 2; i++)
pthread_join(tid[i], NULL);
return 0;
}
or by passing the i by value (by casting it to void*):
#include <stdio.h>
#include <pthread.h>
#include <stdint.h>
void *runner(void * p)
{
printf("line: %d\n", (int)(intptr_t)p);
return 0;
}
int main()
{
pthread_t tid[2];
int ints[2];
for (int i = 0; i < 2; i++){
if(pthread_create(&tid[i], 0, runner, (void*)(intptr_t)i)) return 1;
}
for (int i = 0; i < 2; i++)
pthread_join(tid[i], NULL);
return 0;
}
My program supposed to calculate the matrix product (multiplication) of 2 given matrices using multithreading - each thread calculates one column.
The problem is - when I run it from the terminal, I'm getting few zeros columns. I used debugger to see where the problem is - but at the debugger it works fine every time! I can't figure out where the problem is
How is it possible that I'm getting different values when debugging vs regular execution?
I tried some "simple solutions" from online searching:
reset the linux virtual machine
reset VSCode
and i don't getting any errors or memory leaks but i have no idea what to do further
my code:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <errno.h>
#include <sys/stat.h>
#include <pthread.h>
int MATRIX_DIM=3; //default
int **RESULT_MAT;
struct calcCol{
int **matA;
int **matB;
int **matC;
int dim;
int i;
};
int ijMult(int **matA, int **matB,int dim, int i, int j);
void* colMatCalc(void* s);
void printMatrix(int **mat);
void getMatrix(int **mat);
void freeMatrices(int **matA, int **matB, int **matC);
void* printThreadId(void* arg){
int i = *(int*)arg;
printf("Thread id: %d \n", i);
pthread_exit(NULL);
}
int main(){
pthread_t tid[MATRIX_DIM];
int args[MATRIX_DIM];
pthread_attr_t attr;
pthread_attr_init(&attr);
printf("Enter enter MATRIX_DIM (number between 1 and 10) \n");
scanf("%d",&MATRIX_DIM);
if(MATRIX_DIM>10 || MATRIX_DIM<1)
MATRIX_DIM=3; //default value
//memory allocation for matrices
int **matA = (int **)malloc(MATRIX_DIM * sizeof(int*));
for(int i = 0; i < MATRIX_DIM; i++) matA[i] = (int *)malloc(MATRIX_DIM * sizeof(int));
int **matB = (int **)malloc(MATRIX_DIM * sizeof(int*));
for(int i = 0; i < MATRIX_DIM; i++) matB[i] = (int *)malloc(MATRIX_DIM * sizeof(int));
RESULT_MAT = (int **)malloc(MATRIX_DIM * sizeof(int*));
for(int i = 0; i < MATRIX_DIM; i++) RESULT_MAT[i] = (int *)malloc(MATRIX_DIM * sizeof(int));
struct calcCol s;
s.matA = matA;
s.matB = matB;
s.matC=RESULT_MAT;
s.dim=MATRIX_DIM;
s.i=0;
printf("Enter elements of first matrix \n");
getMatrix(matA);
printf("Enter elements of second matrix \n");
getMatrix(matB);
for(int i=0 ; i<MATRIX_DIM ; i++)
{
args[i]=i;
s.i=i;
pthread_create(&tid[i], &attr, colMatCalc, &s);
}
for(int i=0 ; i<MATRIX_DIM ; i++)
{
if(pthread_join(tid[i], NULL)!=0)
{
perror("pthread_join faild.");
exit(EXIT_FAILURE);
}
printf("Thread %d is terminated.\n", *(int*)(&args[i]));
}
printf("All threads are terminated!\n");
printf("Product of the matrices: \n");
printMatrix(RESULT_MAT);
freeMatrices(matA, matB, RESULT_MAT);
return 0;
}
//calculating (i,j) of the result matrix
int ijMult(int **matA, int **matB, int dim, int i, int j)
{
int sum = 0;
for(int k = 0 ; k < MATRIX_DIM ; k++)
sum = sum + (matA[i][k]*matB[k][j]);
return sum;
}
//calculating the 'i' column of the result matrix
void* colMatCalc(void* arg)
{
struct calcCol s = *(struct calcCol*)arg;
for(int k = 0 ; k < s.dim ; k++)
s.matC[k][s.i] = ijMult(s.matA, s.matB,s.dim, k, s.i);
return 0;
}
void printMatrix(int **mat)
{
for(int i = 0 ; i < MATRIX_DIM ; i++)
{
for(int j = 0 ; j < MATRIX_DIM ; j++)
{
printf("%d \t", mat[i][j]);
}
printf("\n");
}
}
void getMatrix(int **mat)
{
for(int i=0 ; i<MATRIX_DIM ; i++)
{
for(int j=0 ; j<MATRIX_DIM ; j++)
{
scanf("%d",&mat[i][j]);
}
}
}
void freeMatrices(int **matA, int **matB, int **matC)
{
for(int i=0 ; i < MATRIX_DIM ; i++)
{
free(matA[i]);
free(matB[i]);
free(RESULT_MAT[i]);
}
free(matA);
free(matB);
free(RESULT_MAT);
}
I know i don't need to paste the entire code, but i really don't know where is the tricky part...cause again- when i'm in debug mode it works fine.
Input: 3 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6
7 8 9 Expected output 30 36 42 66 81 96
102 126 150
Actual output: same but with zeros column instead (different columns each time)
Thank you.
The problem is with variable s which is shared across all the threads, that is
s.i=i;
When you update s in the loop, every thread will be pointing to latest contents of s.
What you can do is have different instance to each thread as below.
for(int i=0 ; i<MATRIX_DIM ; i++)
{
struct calcCol *s = malloc(sizeof(*s));
s->matA = matA;
s->matB = matB;
s->matC=RESULT_MAT;
s->dim=MATRIX_DIM;
s->i=0;
args[i]=i;
s->i=i;
pthread_create(&tid[i], &attr, colMatCalc, s);
}
With that when you update the content of *s it won't affect other thread's execution.
Make sure you free it once thread is finished its execution.
I'm working on a small program of multithreaded matrix multiplication. My first job is to fill the entry of matrices with a random integer. I met some segment faults after I tried to pass a function pointer to pthread_create. And I think the problem is in function pthread_join.
But there are two issues in general.
The first one is the segment fault does not happen every time. Sometimes the code works, but most of the times it doesn't. So it really confuses me.
The other one is when the code is working, there are always several entries still not initialized, especially for matrix[0][0], it is never initialized. And I don't quite know where to debug that one.
Here's my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#define N 5
#define MAX 10
int A[N][N];
int B[N][N];
int C[N][N];
pthread_t pid[N][N];
typedef struct {
int row, col;
} Pos;
typedef void* (*thread_func)(void*);
void print_matrix(int M[][N]) {
int i, j;
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
printf("%3d", M[i][j]);
if (j < N - 1) {
printf(", ");
}
}
printf("\n");
}
}
void join_threads(void) {
int i, j;
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
pthread_join(pid[i][j], NULL);
}
}
}
void* fill_entry(void* arg) {
Pos* pos = (Pos*)arg;
A[pos->row][pos->col] = rand() % MAX;
B[pos->row][pos->col] = rand() % MAX;
return NULL;
}
void dispatch_jobs(thread_func job_func) {
int i, j;
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
Pos pos;
pos.row = i;
pos.col = j;
if (pthread_create(&pid[i][j], NULL, job_func, (void*)&pos)) {
perror("pthread_create");
exit(-1);
}
}
}
}
int main(void) {
srand(time(NULL));
dispatch_jobs(&fill_entry);
join_threads();
printf("Matrix A:\n");
print_matrix(A);
printf("Matrix B:\n");
print_matrix(B);
return 0;
}
Pos pos;
pos.row = i;
pos.col = j;
if (pthread_create(&pid[i][j], NULL, job_func, (void*)&pos)) {
perror("pthread_create");
exit(-1);
}
You are passing a pointer to a local variable to the threads. Once the thread tries to access the data, i.e. dereferences the pointer, the variable is long gone, reused, and contains garbage data.
I have a quick question. I'm learning about semaphores and I want only four threads to be able to access someFunction() at any given time. This function needs to execute num_task times. This is what I have so far, but valgrind is throwing some errors saying that I have possible memory leaks. Please tell me where I'm going wrong and how to go about fixing this. Thank you!
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <pthread.h>
#include <semaphore.h>
sem_t s;
typedef struct Data Data;
struct Data {
int index;
int j;
};
void* someFunction(void* arg){
// make sure only four threads access this function at once
sem_wait(&s);
Data* a = arg;
printf("i%d j%d\n", a->index, a->j);
sleep(1);
free(a);
sem_post(&s);
return 0;
}
int main(void){
int num_task = 10; // i need to call someFunction() 9000 times
int num_threads = 4;
sem_init(&s, 0, num_threads);
int j = 0;
pthread_t thread_ids[num_threads];
for (int i = 0; i < num_task; i ++){ // these are our columns
sem_wait(&s);
if (j > num_threads - 1){
j = 0; // j goes 0 1 2 3 0 1 2 3 0 1 2 3 ....
}
Data* a = malloc(sizeof(Data));
a->index = i;
a->j = j;
printf("MAIN j%d\n", j);
pthread_create(thread_ids + j, NULL, someFunction, a);
j ++;
sem_post(&s);
}
for (int i = 0; i < num_threads; i ++){
pthread_join(thread_ids[i], NULL);
}
sem_destroy(&s);
return 0;
}