Check thread ending condition - c

I have a process with 2 threads. if one of the 2 threads is done executing his instructions, then the other should stop too. And the process should end. How to check if one of the threads has done executing the instructions? This is the code that i have written so far.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int read = 0;
int timeLeft = 0;
void *readFromFile(void *myFile){
char *theFile;
theFile = (char*) myFile;
char question[100];
char answer[100];
FILE *file = fopen(theFile, "r");
if(file != NULL){
while(fgets(question,sizeof question,file) != NULL){
fputs(question, stdout);
scanf("%s", &answer);
}
read = 1;
fclose(file);
printf("Done with questions!\n");
pthread_exit(
}
else{
perror(theFile);
}
}
void displayTimeLeft(void *arg){
int *time;
time = (int*) arg;
int i;
for(i = time; i >= 0; i -= 60){
if( i / 60 != 0){
printf("You have %d %s left.\n", i/60,(i/60>1)?"minutes":"minute");
sleep(60);
}
else{
timeLeft = 1;
printf("The time is over \n");
break;
}
}
}
int main(){
pthread_t thread1;
pthread_t thread2;
char *file = "/home/osystems01/laura/test";
int *time = 180;
int ret1;
int ret2;
ret1 = pthread_create(&thread1, NULL, readFromFile,&file);
ret2 = pthread_create(&thread2, NULL, displayTimeLeft,&time);
printf("Main function after pthread_create");
while(1){
//pthread_join(thread1,NULL);
//pthread_join(thread2,NULL);
if(read == 1){
pthread_cancel(thread2);
pthread_cancel(thread1);
break;
}
else if(timeLeft == 0){
pthread_cancel(thread1);
pthread_cancel(thread2);
break;
}
}
printf("After the while loop!\n");
return 0;
}

You can declare a global flag variable and set it to false initially.
Whenever a thread reaches its last statement it sets the flag to true. And whenever a thread starts executing it will first check the flag value, if it false i.e. no other thread has updated it continues execution else returns from the function

First of all you might want to read the pthread_cancel manual page (and the manual pages for the associated pthread_setcancelstate and pthread_setcanceltype functions). The first link contains a nice example.
Another solution is to have e.g. a set of global variables that the threads checks from time to time to see if they should exit or if another thread have exited.
The problem with using e.g. pthread_cancel is that the thread is terminated without letting you clean up after your self easily, which can lead to resource leaks. Read about pthread_key_create about one way to overcome this.

Related

Only three of my five threads are executing, synchronizing using mutexes

I am doing an academic exercise for an OS class where we synchronize five detached threads using ONLY mutex locks and unlocks. We "CANNOT force the threads into any serial execution. Once spawned they must be free from external influences (other than the mutexes). The parent should NOT employ a pthread_join."
I am spawning 5 threads, detaching them and then using each threads to read in data and update a global variable. Currently my code spawns the 5 threads but only three of them output their ID's and none of them get into the while loop. Any help/advice here would be appreciated!
Output:
thread: 6156515168
thread: 6156515192
thread: 6156515176
There is a sleep in main which if uncommented provides the expected output, but this would be forcing a serial execution..
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <pthread.h>
pthread_mutex_t mutex_lock = PTHREAD_MUTEX_INITIALIZER; // declaring mutex
int FileNameHelper=1;
int balance=0;
void* detatchedThread(void *param){
long tid = (long)param;
char* base = "data";
char filename[256];
char buf[100];
sprintf(filename, "%s%d.in", base, FileNameHelper); //creates data1.in, data2.in...
FileNameHelper ++;
FILE *inputFile = fopen(filename, "r");
printf ("thread: %ld\n", tid);
// critical sec line
if(fgets(buf, sizeof buf, inputFile) == NULL)
return NULL; // could not read first line
sleep(1); // make sure each thread runs long enough to get the random update behavior required.
pthread_mutex_lock(&mutex_lock); //we are in the critical section, lock mutex
while(fgets(buf, sizeof buf, inputFile) != NULL) {
int val;
if(sscanf(buf, "%d", &val) != 1){
break;
}
printf("%d\n", val);
balance += val;
printf ("Account balance after thread %ld is $%d\n", tid, balance);
}
pthread_mutex_unlock(&mutex_lock);
if(buf[0] != 'W')
return NULL;// last line data was invalid
pthread_exit(NULL);
}
int main(){
pthread_t th[5];
//initialize the mutex
if(pthread_mutex_init(&mutex_lock, NULL) != 0){
printf("\nmutex init has failed\n");
return 1;
}
//call the 5 threads, Detach the threads once they are created.
for (int i = 0; i < 5; i++){
pthread_create(&th[i], NULL, detatchedThread, (void *)&th[i]);
pthread_detach(th[i]);
//sleep(1); uncommenting this line gives me the expected behavior
}
pthread_mutex_destroy(&mutex_lock);
return 0;
}

How to detect starvation in reader-writer problem

I have a question about this piece of code I have. It is the classic readers-writers problem. I followed the pseudo-code found on this wikipedia page for the first problem that has writers starving. I would like to know how I would actually notice the starvation of the writers going on.
I tried putting print statements of the shared_variable in various places, but this didn't give me much insight. But maybe I just didn't understand what was going on. Would someone be able to explain to me how I could visually see the starvation happening? Thank you!
The number of attempts that the reader or writer would attempt to read or write is given as a command line argument.
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <semaphore.h>
#include <pthread.h>
// Compile it like so: gcc assignment2.c -lpthread
// Shared variables (semaphore and integer)
static sem_t rw_mutex;
static sem_t mutex;
static int read_count = 0;
// Shared variable
int shared_variable = 0;
static void *writerAction(void *arg){
int number_attempt = *((int *) arg);
int attempt = 0;
do{
sem_wait(&rw_mutex);
shared_variable = shared_variable + 10;
sem_post(&rw_mutex);
attempt++;
}while(attempt < number_attempt);
}
static void *readerAction(void *arg){
int number_attempt = *((int *) arg);
int attempt = 0;
do{
sem_wait(&mutex);
read_count++;
// waiting to be able to read for the possible writer
if (read_count == 1 ){
sem_wait(&rw_mutex); // get the lock so that writter can't write!
}
// Release the read_count variable
sem_post(&mutex);
sem_wait(&mutex);
read_count--;
if (read_count == 0){
sem_post(&rw_mutex); // release the lock so that writter can write
}
sem_post(&mutex);
attempt++;
} while(attempt < number_attempt);
}
int main(int argc, char *argv[]) {
int number_writers = 10;
int number_readers = 500;
int reader_repeat_count = atoi(argv[2]);
int writer_repeat_count = atoi(argv[1]);
// Instantiating the threads for the writters and readers
pthread_t writer_threads[number_writers];
pthread_t reader_threads[number_readers];
// Initation of semaphores
sem_init(&rw_mutex, 0, 1);
sem_init(&mutex, 0, 1);
printf("Start creation of Readers\n");
for(int i = 0; i <number_readers; i++){
pthread_create(&reader_threads[i], NULL, readerAction, &reader_repeat_count);
}
printf("Start creation of Writers\n");
for(int i = 0; i < number_writers; i++){
pthread_create(&writer_threads[i], NULL, writerAction, &writer_repeat_count);
}
// All the actions is hapenning here
printf("Wait for Readers\n");
for(int i = 0; i < number_readers; i++){
printf("Waiting for : %d\n",i);
pthread_join(reader_threads[i], NULL);
}
printf("Wait for Writers\n");
// Collect all the writers
for(int i = 0; i < number_writers; i++){
printf("Waiting for : %d\n",i);
pthread_join(writer_threads[i], NULL);
}
// Results
printf("The shared variable is : %d\n",shared_variable);
}
First of all there is a syntax error, the return type of writerAction and readerAction should be void not void*
In order to see writer starvation you can print "writer trying to write" just before writer is trying to acquire the rw_mutex, the call to sem_wait(&rw_mutex). Add another print when the writer has updated the shared variable, inside the critical section. Add one more printf just after the the entry section of the reader. Which is this code.
// Release the read_count variable
sem_post(&mutex);
printf("reader reading shared value %d\n", shared_variable);
Now when you run the code with large repeat count, You will see "writer trying to write" then you will see a large number of reader printouts instead of the one from writer updating the shared variables, which will prove that the readers are starving the writer by not allowing it to update the variable.

Cat unix command multithread implementation

Hi im trying to implement faster cat than the one provided.
My current implementation looks like this:
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#define BUF_SIZE 1024*1024*1024
char buffer[BUF_SIZE];
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond_var = PTHREAD_COND_INITIALIZER;
pthread_cond_t cond_var2 = PTHREAD_COND_INITIALIZER;
int readed = 0;
/*
Read characters from standard input and saves them to buffer
*/
void *consumer(void *data) {
int r;
while(1) {
//---------CRITICAL CODE--------------
//------------REGION------------------
pthread_mutex_lock(&mutex);
if (readed > 0)
{
pthread_cond_wait(&cond_var2, &mutex);
}
r = read(0, buffer, BUF_SIZE);
readed = r;
pthread_cond_signal(&cond_var);
pthread_mutex_unlock(&mutex);
//------------------------------------
if (r == -1){
printf("Error reading\n");
}
else if (r == 0) {
pthread_exit(NULL);
}
}
}
/*
Print chars readed by consumer from standard input to standard output
*/
void *out_producer(void *data) {
int w;
while(1){
//---------CRITICAL CODE--------------
//-------------REGION-----------------
pthread_mutex_lock(&mutex);
if (readed == 0)
{
pthread_cond_wait(&cond_var, &mutex);
}
w = write(1, buffer, readed);
readed = 0;
pthread_cond_signal(&cond_var2);
pthread_mutex_unlock(&mutex);
//------------------------------------
if (w == -1){
printf("Error writing\n");
}
else if (w == 0) {
pthread_exit(NULL);
}
}
}
What would you suggest to make it faster?
Any ideas?
I was thinking about the BUF_SIZE, what would you think would be optimal size of buffer?
Main just makes the threads:
int main() {
// Program RETURN value
int return_value = 0;
// in - INPUT thread
// out - OUTPUT thread
pthread_t in, out;
// Creating in thread - should read from standard input (0)
return_value = pthread_create(&in , NULL, consumer, NULL);
if (return_value != 0) {
printf("Error creating input thread exiting with code error: %d\n", return_value);
return return_value;
}
// Creating out thread - should write to standard output (1)
return_value = pthread_create(&out, NULL, out_producer, NULL);
if (return_value != 0) {
printf("Error creating output thread exiting with code error: %d\n", return_value);
return return_value;
}
return_value = pthread_join(in, NULL);
return_value = pthread_join(out, NULL);
return return_value;
}
How exactly is adding threads to cat going to make it faster? You can't just throw parallelism at any program and expect it to run faster.
Cat basically just transports every line of input (usually from a file) to output. Since it's important that the lines are in order, you have to use mutual exclusion to avoid racing.
The upper bound of the speed (the fastest that cat can run) in parallel cannot be higher than cat in serial, since every thread must perform the serial actions, along with the cost of synchronization.

Thread Termination Condition

I'm writing a producer-consumer thread program in C. Everything in my program is working perfectly with one major exception. When I have more than one consumer thread, which is pretty much always, only the first consumer thread will actually terminate. I've tried absolutely everything that I can think of, but the problem persists. Here's my code, with the guts of it stripped out, so that you can see just the part that is relevant.
I can see from my output that both of the termination condition variables become zero, which is of course why the first consumer thread terminates. But why don't the other consumer threads also terminate?
Thank you!
sem_t full, empty, mutex;
int threads;
int to_consume;
FILE* inputfp[5];
FILE* outputfp = NULL;
char in[BUF];
void* p(void* inpFile) {
while (fscanf(inpFile, FMTSTRING, in) > 0) {
sem_wait(&empty);
sem_wait(&mutex);
// production code here
to_consume++;
sem_post(&mutex);
sem_post(&full);
}
fclose (inpFile);
sem_wait(&mutex);
threads--;
sem_post(&mutex);
return NULL;
}
void* c() {
int continuing = 1;
while (continuing) {
sem_wait(&full);
sem_wait(&mutex);
//consumption code here
to_consume--;
fprintf("%d %d\n", threads, to_consume); //these both go to zero by the end
if ( (threads <= 0) && (to_consume <= 0) ) {
continuing = 0;
}
sem_post(&mutex);
sem_post(&empty);
}
return NULL;
}
int main (int argc, char* argv[]) {
int i;
int con_threads;
con_threads = 3;
to_consume = 0;
pthread_t *pr_thread[argc-2];
pthread_t *con_thread[2];
sem_init(&full, 0, 0);
sem_init(&empty, 0, 50);
sem_init(&mutex, 0, 1);
for (i = 0; i < (argc-2); i++) {
pr_thread[i] = (pthread_t *) malloc(sizeof(pthread_t));
inputfp[i] = fopen(argv[i+1], "r");
int rc = pthread_create (pr_thread[i], NULL, p, inputfp[i]);
sem_wait(&mutex);
threads++;
sem_post(&mutex);
}
outputfp = fopen(argv[(argc-1)], "wb");
for (i = 0; i con_threads 3; i++) {
con_thread[i] = (pthread_t *) malloc(sizeof(pthread_t));
int rc = pthread_create (con_thread[i], NULL, c, NULL);
}
for (i = 0; i < (argc - 2); i++) {
pthread_join(*pr_thread[i], 0);
free(pr_thread[i]);
}
for (i = 0; i con_threads 3; i++) {
fprintf(stderr, "About to close consumer thread %d.\n", i);
pthread_join(*res_thread[i], 0);
fprintf(stderr, "Consumer thread %d closed successfully.\n", i);
free(res_thread[i]);
}
printf ("About to close the output file.\n");
/* Close the output file */
fclose (outputfp);
return EXIT_SUCCESS;
}
I think your problem is that you don't post full again when the first consumer detects that there are no threads left, so the second consumer is waiting on full but the signal will never arrive. You may need a count of the consumers, though for a first pass (proof of concept), you can leave full with a post that is never read.

Unable to Find Segfault Cause

The program is supposed to create x amount of threads based on the arguments that are passed to it. argv[1] is the amount main is supposed to sleep, argv[2] is the number of propucer threads, and argv[3] is the number of consumer threads. The program compiles fine and the command I have been using to run it is: program 10 1 1.
I've been staring at this code for a while now and I can't seem to find what is causing the segmentation fault. Maybe a second set of eyes will be able to pick it quickly.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <pthread.h>
#include "buffer.h"
void *producer(void *);
void *consumer(void *);
// Semaphores
sem_t empty;
sem_t full;
pthread_mutex_t mutex;
// Buffer
int placed = 0;
buffer_item buffer[BUFFER_SIZE];
int insert_item(buffer_item item){
/* INSERT ITEM INTO BUFFER */
int z;
sem_wait(&empty);
//mutex lock
z = pthread_mutex_lock(&mutex);
if (z != 0){
return -1;
}
buffer[placed] = item;
//mutex unlock
z = pthread_mutex_unlock(&mutex);
if (z != 0){
return -1;
}
sem_post(&full);
placed++;
printf("producer produced %d\n", item);
}
int remove_item(buffer_item *item){
/* REMOVE ITEM FROM BUFFER */
int m;
placed--;
sem_wait(&full);
//mutex lock
m = pthread_mutex_lock(&mutex);
if (m != 0){
return -1;
}
buffer[placed] = -1;
//mutex unlock
m = pthread_mutex_unlock(&mutex);
if (m != 0){
return -1;
}
sem_post(&empty);
printf("consumer consumed %d\n", rand);
return 0;
}
// Main
int main(int argc, char *argv[]){
int sleepNum, pThreadNum, cThreadNum, p;
sleepNum = atoi(argv[1]);
pThreadNum = atoi(argv[2]);
cThreadNum = atoi(argv[3]);
// Initialize Semaphores & mutex
sem_init(&empty, 0, BUFFER_SIZE);
sem_init(&full, 0, 0);
pthread_mutex_init(&mutex, NULL);
// Create producer thread
pthread_t tid[pThreadNum];
int g=pThreadNum-1;
while(g >= 0){
p = pthread_create(&tid[g], NULL, producer, NULL);
g--;
}
printf("created prod thread");
// Create consumer thread
pthread_t kid[cThreadNum];
g = cThreadNum-1;
while(g >= 0){
p = pthread_create(&kid[g], NULL, consumer, NULL);
g--;
}
// Sleep for argv[0]
sleep(sleepNum);
// Destroy mutex & semaphores
sem_destroy(&empty);
sem_destroy(&full);
p = pthread_mutex_destroy(&mutex);
// Exit
exit(0);
}
// Producer
void *producer(void *param){
buffer_item rand;
unsigned int *seed;
int b;
while(1){
sleep(2);
rand = rand_r(seed);
b = insert_item(rand);
if (b < 0){
printf("Error producing item.");
}
}
}
// Consumer
void *consumer(void *param){
buffer_item rand;
int d;
while(1){
sleep(2);
d = remove_item(&rand);
if (d < 0){
printf("Error removing item");
}
}
}
Thanks in advance!
On Unix, you can get the backtrace from a segmentation fault by dumping core and examing the corefile in gdb.
$ ulimit -c <max core file size in 1k blocks>
$ gdb program core
gdb> bt
should dump the backtrace, and you can see exactly which line segfaulted.
In the producer you are using an uninitialized pointer. Try allocating some memory for it using malloc. I'm not explaining exactly what it is because you tagged this as homework.
Also don't rely on the output from printf statements to tell you where the program got to when using threads. It helps if you flush the output stream explicitly after each printf, then you'll almost get an idea of the right sequence of events.
compile your program with -g, as gcc -g program.c -lpthread
then
gdb a.out
set breakpoint as
b main
start
and then use s for step by step execution and see where it is falling.
As someone already mentioned that your producer function has uninitialized pointer unsigned int *seed;
also this program has lost wake-up problem associated with it, along with normal unlocking problem ( as in function insert item, what if insert_item thread context-switched before doing placed++. )
Here's a great article for finding the causes of segfaults.
Link
Link mirrored here, in case it ever goes down.... you never know.

Resources