How to write to multiple files using threads with C - c

This is my code using threads:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
void *t1(void *arg)
{
FILE *file = fopen((char *) arg, "w");
for (long long int i = 0; i <= 100000000; i++) {
fprintf(file, "--LINE-- <%lld>\n", i);
}
fclose(file);
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t thread1, thread2, thread3, thread4;
pthread_create(&thread1, NULL, t1, "FILE_1.txt");
pthread_create(&thread2, NULL, t1, "FILE_2.txt");
pthread_create(&thread3, NULL, t1, "FILE_3.txt");
pthread_create(&thread4, NULL, t1, "FILE_4.txt");
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
pthread_join(thread3, NULL);
pthread_join(thread4, NULL);
return 0;
}
This is code without threads, I just call the function 4 times:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
void *t1(void *arg)
{
FILE *file = fopen((char *) arg, "w");
for (long long int i = 0; i <= 100000000; i++) {
fprintf(file, "--LINE-- <%lld>\n", i);
}
fclose(file);
return NULL;
}
int main(int argc, char *argv[])
{
t1("FILE_1.txt");
t1("FILE_2.txt");
t1("FILE_3.txt");
t1("FILE_4.txt");
return 0;
}
I get about the same time as with threads. (I used code to get the time however the question was being flagged as if it was asking how to get the time it takes to run a function so I had to remove it). Is this a problem with fprintf? How could I write to multiple files at the same time? Is there a better solution than using threads?

Related

Use semaphores in C to protect variable within for loop

I'm trying to use semaphores to avoid that a global variable is changed by threads and this variable is supposed to increment within the for loop. My main objective is to protect the variable cnt from the threads so it can increment within the for loop. However, I don't know how to do it because this is the first time I work with semaphores.
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
sem_t semaphore;
int cnt = 0; //global shared variable
void *threadProd(void *param); //threads call this function.
int main(int argc, char *argv[])
{
int niters;
pthread_t tid1, tid2; //thread ids
sem_init(&semaphore,0,1);
if (argc != 2){
printf("Usage: %s <niters>\n", argv[0]);
exit(0);
}
niters = atoi(argv[1]);
pthread_create(&tid1, NULL, threadProd, &niters);
pthread_create(&tid2, NULL, threadProd, &niters);
pthread_join(tid1, NULL); //wait for thread to finish
pthread_join(tid2, NULL);
//check answer:
if(cnt != (2 * niters))
printf("Incorrect answer, cnt = %d\n", cnt);
else
printf("Correct answer, cnt = %d\n", cnt);
sem_destroy(&semaphore);
exit(0);
}
//Thread routine
void *threadProd(void *vargp)
{
sem_wait(&semaphore);
int upper = *((int *) vargp);
for (int i = 0; i < upper; i++)
cnt ++;
sem_post(&semaphore);
return NULL;
}

segmentation fault in multithread program

I'm trying to write a program that uses 3 threads with a shared memory. the shared memory is an array with 101 values. the first value shared memory[0](initialized to 0) is status value which determines which operation should take place. the three threads do
The first one should fill the shared memory array with 100 random values. and set the status value to 1.
The second should print the product of the 100 random values (from index 1 to 100). and set the status value to 2.
The third should print the average of the 100 random variables. and set the status value to 0. so that thread one fill the shared memory with different random variables.
this is my code
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
unsigned int product=0;
float avg=0;
int* shared_memory;
int status=0;
void productAllThread();
void averageAllThread();
void *parentProcess();
void *prodAll();
void *avgAll();
void initializeArray();
int main(int argc, const char * argv[])
{
time_t t;
key_t key = 9876;
// Create shared memory area
int shm_id = shmget(key, sizeof(int)*101, IPC_CREAT | 0666);
// initialize the random variable
srand((unsigned) time(&t));
// Create shared memory
shared_memory=shmat(shm_id, NULL, 0);
//create threads
pthread_t tid1, tid2, tid3;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&tid1, &attr, parentProcess, NULL);
pthread_create(&tid2, &attr, prodAll, NULL);
pthread_create(&tid3, &attr, avgAll, NULL);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
pthread_join(tid3, NULL);
return 0;
}
void initializeArray() {
shared_memory[0]=0;
status=shared_memory[0];
int i= 0;
printf("Initial Array:{");
for(i=1; i<100; i++)
{
shared_memory[i]=rand()% 50;
printf("%d,", shared_memory[i]);
}
printf("}\n");
}
void *parentProcess()
{
while(1)
{
status=shared_memory[0];
if(status==0) {
// initialize array
initializeArray();
shared_memory[0]=1;
} else {
sleep(10);
}
}
}
void averageAllThread() {
while(1) {
status=shared_memory[0];
if(status==2)
{
avgAll();
wait(NULL);
printf("Avg:%.2f\n", avg);
shared_memory[0]=0;
} else {
sleep(5);
}
}
}
void productAllThread() {
while(1){
status=shared_memory[10];
if (status==1)
{
prodAll();
wait(NULL);
printf("Sum:%d\n",product);
shared_memory[0]=2;
} else {
sleep(5);
}
}
}
void *prodAll()
{
while(1){
int i=1;
product=0;
for(i=1; i<100; i++)
{
product=product+shared_memory[i];
}
}
}
void *avgAll()
{
while(1){
int i=0;
avg=0;
for(i=1; i<100; i++)
{
avg=avg+shared_memory[i];
}
avg=avg/100;
}
}
when I run it in the terminal, it gives me this error
"Segmentation fault: 11"
what might cause this type of errors? If this error is fixed will the program work fine to do the job I want it to do?
I found a few problems in your program:
You are calling the wrong functions to start your threads:
pthread_create(&tid1, &attr, parentProcess, NULL);
pthread_create(&tid2, &attr, prodAll, NULL);
pthread_create(&tid3, &attr, avgAll, NULL);
Should be:
pthread_create(&tid1, &attr, parentProcess, NULL);
pthread_create(&tid2, &attr, productAllThread, NULL);
pthread_create(&tid3, &attr, averageAllThread, NULL);
You have a few calls to wait() like this:
wait(NULL);
You should remove all of them.
The while loops in avgAll() and prodAll() should be removed since there are already while loops in the callers of those functions.
The call to srand() should be made from parentProcess() otherwise it might not affect the rand() calls in that thread.

Threads in c, what am I missing here?

I'm trying to create a thread, and I cannot figure out what I am doing wrong here. It's very basic, I just want to make sure I can get the thread created before I delve into what I'll be doing in the thread. Here's my code.
//prog.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <pthread.h>
#include <stdbool.h>
#include <unistd.h>
int threadCount =0; //Global variable to hold our thread counter
//this is the function that gets called when a thread is created
void *threadCreate(void* arg){
printf("Thread #%d has been created\n", threadCount);
threadCount++;
int param = (int)arg;
printf("We were sent: %d\n", param);
printf("Now the thread will die\n");
threadCount--;
pthread_exit(NULL);
}
//main
int main(int argc, char *argv[]){
pthread_t tid;
int numski = 50;
int res;
res = pthread_create(&tid, NULL, threadCreate, (void*)numski);
if (res){
printf("Error: pthread_create returned %d\n", res);
exit(EXIT_FAILURE);
}
return 0;
}
I am compiling using the following command:
gcc -Wall -pthread -std=c99 prog.c -o Prog
And when I try to run it, I get no output at all.
Main is exiting right away, and therefore your process is dying right away. End it with pthread_join to wait for them. Here is one example I googled, which contains the following example code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *print_message_function( void *ptr );
main()
{
pthread_t thread1, thread2;
const char *message1 = "Thread 1";
const char *message2 = "Thread 2";
int iret1, iret2;
/* Create independent threads each of which will execute function */
iret1 = pthread_create( &thread1, NULL, print_message_function, (void*) message1);
iret2 = pthread_create( &thread2, NULL, print_message_function, (void*) message2);
/* Wait till threads are complete before main continues. Unless we */
/* wait we run the risk of executing an exit which will terminate */
/* the process and all threads before the threads have completed. */
pthread_join( thread1, NULL);
pthread_join( thread2, NULL);
printf("Thread 1 returns: %d\n",iret1);
printf("Thread 2 returns: %d\n",iret2);
exit(0);
}
void *print_message_function( void *ptr )
{
char *message;
message = (char *) ptr;
printf("%s \n", message);
}

critical section definition

in this example code below, where is the "critical section" exatly?. after "sem_wait()" ?
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
void * thread_snd(void *arg);
void * thread_rcv(void *arg);
sem_t bin_sem;
int number=0;
char thread1[]="A Thread";
char thread2[]="B Thread";
char thread3[]="C Thread";
int main(int argc, char **argv)
{
pthread_t t1, t2, t3;
void *thread_result;
int state;
state = sem_init(&bin_sem, 0, 0);
pthread_create(&t1, NULL, thread_snd, &thread1);
pthread_create(&t2, NULL, thread_rcv, &thread2);
pthread_create(&t3, NULL, thread_rcv, &thread3);
pthread_join(t1, &thread_result);
pthread_join(t2, &thread_result);
pthread_join(t3, &thread_result);
printf("number : %d \n", number);
sem_destroy(&bin_sem);
return 0;
}
void * thread_snd(void * arg)
{
int i;
for(i=0; i<4; i++)
{
while(number != 0)
sleep(1);
number++;
printf("%s, number : %d \n", (char*)arg, number);
sem_post(&bin_sem);
}
}
void * thread_rcv(void * arg)
{
int i;
for(i=0; i<2; i++)
{
sem_wait(&bin_sem);
number--;
printf("%s, number : %d \n", (char*)arg, number);
}
}
There actually is no "critical section" in the provided code, there is only "sync point", and yes that is realized with the semaphore. The critical section can also be implemented with semaphore, but then the thread must use both sem_wait() and sem_post() but in most cases mutexes are used for critical sections (if only one thread is ever supposed to enter it).

POSIX C Threads. Mutex example. Don't work as expected

I have a big problem, I can't figure out why mutexes in C don't work as I expect.
This is my code:
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
pthread_t mythread;
pthread_mutex_t mymutex;
void *anotherFunc(void*)
{
pthread_mutex_lock(&mymutex);
for(int i = 0; i < 100; i++)
printf("anotherFunc\n");
pthread_mutex_unlock(&mymutex);
pthread_exit(NULL);
}
void *func(void*)
{
pthread_mutex_lock(&mymutex);
for(int i = 0; i < 100; i++)
printf("func\n");
pthread_mutex_unlock(&mymutex);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_mutex_init(&mymutex, NULL);
pthread_create(&mythread, NULL, func, NULL);
pthread_create(&mythread, NULL, anotherFunc, NULL);
pthread_mutex_destroy(&mymutex);
pthread_exit(NULL);
return EXIT_SUCCESS;
}
What I expect to happen is the program to print first 100 "func" messages and then 100 "anotherFunc" messages. What I expect is execution to reach func and lock the mutex. When the execution reaches anotherFunc, I expect to wait until func unlocks the mutex. But I get interfered messages like
func
func
func
anotherFunc
anotherFunc
anotherFunc
func
anotherFunc
I don't understand how this thing works. Please help!
pthread_create(&mythread, NULL, func, NULL);
pthread_create(&mythread, NULL, anotherFunc, NULL);
pthread_mutex_destroy(&mymutex);
You're destroying the mutex before the threads are done with it, so all bets are off. You'll probably want to pthread_join the 2 threads before destroying it.
I got few comiplation errors
I couldn't declare int i in for loop
Used an argument name arg as an argument for threads "func" and "anotherFunc"
I have used pthread_join before destroying the mutex.
In this way I am destroying my mutex "mymutex" after both threads "func" and "anotherFunc" have completed their execution
Also each threads now has their own thread id "mythread1" and "mythread2" so in this way I can use pthread_join() function for each thread
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
pthread_t mythread1, mythread2;
pthread_mutex_t mymutex;
void *anotherFunc(void *arg)
{
pthread_mutex_lock(&mymutex);
int i;
for(i = 0; i < 100; i++)
printf("anotherFunc\n");
pthread_mutex_unlock(&mymutex);
pthread_exit(NULL);
}
void *func(void *arg)
{
pthread_mutex_lock(&mymutex);
int i;
for(i = 0; i < 100; i++)
printf("func\n");
pthread_mutex_unlock(&mymutex);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_mutex_init(&mymutex, NULL);
pthread_create(&mythread1, NULL, func, NULL);
pthread_create(&mythread2, NULL, anotherFunc, NULL);
pthread_join(mythread1, NULL);
pthread_join(mythread2, NULL);
pthread_mutex_destroy(&mymutex);
return EXIT_SUCCESS;
}

Resources