Reputation: 549
I'm trying to create a thread for every line in a file and pass to a thread function this line from a file as an argument in c programming in Linux.
Here is my code:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
/* perform_work function args struct */
typedef struct {
char arg_1[20];
} arg_struct;
/* counter fo threads */
int count = 0;
/* function to execute in every thread */
void *perform_work(void *argument)
{
arg_struct *actual_args = argument;
printf("\nthread processing done, arg_1 = %d\n", *actual_args->arg_1);
++count;
printf("Thread number = %d\n", count);
return NULL;
}
/* main function */
int main(void)
{
int lines_allocated = 128;
int max_line_len = 100;
/* allocate lines of text */
char **words = (char **)malloc(sizeof(char*)*lines_allocated);
if (words==NULL) {
fprintf(stderr,"Out of memory (1).\n");
exit(1);
}
FILE *fp = fopen("file.txt", "r");
if (fp == NULL) {
fprintf(stderr,"Error opening file.\n");
exit(2);
}
int i;
for (i=0;1;i++) {
int j;
/* have we gone over our line allocation? */
if (i >= lines_allocated) {
int new_size;
/* Double our allocation and re-allocate */
new_size = lines_allocated*2;
words = (char **)realloc(words,sizeof(char*)*new_size);
if (words==NULL){
fprintf(stderr,"Out of memory.\n");
exit(3);
}
lines_allocated = new_size;
}
/* allocate space for the next line */
words[i] = malloc(max_line_len);
if (words[i]==NULL)
{
fprintf(stderr,"Out of memory (3).\n");
exit(4);
}
if (fgets(words[i],max_line_len-1,fp)==NULL)
break;
/* get rid of CR or LF at end of line */
for (j=strlen(words[i])-1;j>=0 && (words[i][j]=='\n' || words[i][j]=='\r');j--)
;
words[i][j+1]='\0';
}
/* close file */
fclose(fp);
pthread_t threads[i];
int thread_args[i];
int result_code, index;
int *ptr[i];
/* create all threads one by one */
for (index = 0; index < i; ++index) {
arg_struct *args = malloc(sizeof *args);
strcpy(args->arg_1, words[index]);
result_code = pthread_create(&threads[index], NULL, perform_work, args);
assert(0 == result_code);
}
/* wait for each thread to complete */
for (index = 0; index < i; ++index) {
// block until thread 'index' completes
result_code = pthread_join(threads[index], (void**)&(ptr[index]));
//printf("In main: thread %d has completed\n", index);
assert(0 == result_code);
}
printf("In main: All threads completed successfully\n");
int j;
for(j = 0; j < i; j++)
printf("%s\n", words[j]);
/* good practice to free memory */
for (;i>=0;i--)
free(words[i]);
free(words);
return 0;
}
I'm stuck on this code. It works but threads function get some strange args value.
Output:
thread processing done, arg_1 = 51
Thread number = 1
thread processing done, arg_1 = 50
Thread number = 2
thread processing done, arg_1 = 55
Thread number = 3
thread processing done, arg_1 = 49
Thread number = 4
thread processing done, arg_1 = 53
Thread number = 5
thread processing done, arg_1 = 52
Thread number = 6
thread processing done, arg_1 = 54
Thread number = 7
thread processing done, arg_1 = 56
Thread number = 8
thread processing done, arg_1 = 57
Thread number = 9
thread processing done, arg_1 = 49
Thread number = 10
thread processing done, arg_1 = 49
Thread number = 11
thread processing done, arg_1 = 49
thread processing done, arg_1 = 49
Thread number = 13
thread processing done, arg_1 = 49
Thread number = 14
thread processing done, arg_1 = 49
Thread number = 15
thread processing done, arg_1 = 49
Thread number = 16
thread processing done, arg_1 = 49
Thread number = 17
thread processing done, arg_1 = 49
Thread number = 18
thread processing done, arg_1 = 50
Thread number = 19
thread processing done, arg_1 = 49
Thread number = 20
Thread number = 12
In main: All threads completed successfully
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
But the file contains this lines:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
I want threads function args would be line by line read from a file.
In the code above I read from a file to array first and then for every line in an array create a thread. Is it possible to create threads in a loop when reading a file without additional array? If yes, how? If not, what to do if the lines would be to much? Help me please.
Upvotes: 0
Views: 2107
Reputation: 24229
I've noticed two problems:
printf("\nthread processing done, arg_1 = %d\n", *actual_args->arg_1);
should be:
printf("\nthread processing done, arg_1 = %s\n", actual_args->arg_1);
as we're printing string, not code of first symbol
for (index = 0; index < i; ++index) {
arg_struct *args = malloc(sizeof *args);
strcpy(args->arg_1, words[index]);
result_code = pthread_create(&threads[index], NULL, perform_work, args);
assert(0 == result_code);
}
should be:
arg_struct *args = malloc(sizeof(arg_struct)*i);
for (index = 0; index < i; ++index) {
strcpy(args[index].arg_1, words[index]);
result_code = pthread_create(&threads[index], NULL, perform_work, &args[index]);
assert(0 == result_code);
}
Upvotes: 1