How to resolve the algorithm Synchronous concurrency step by step in the C programming language

Published on 7 June 2024 03:52 AM
#C

How to resolve the algorithm Synchronous concurrency step by step in the C programming language

Table of Contents

Problem Statement

The goal of this task is to create two concurrent activities ("Threads" or "Tasks", not processes.) that share data synchronously. Your language may provide syntax or libraries to perform concurrency. Different languages provide different implementations of concurrency, often with different names. Some languages use the term threads, others use the term tasks, while others use co-processes. This task should not be implemented using fork, spawn, or the Linux/UNIX/Win32 pipe command, as communication should be between threads, not processes. One of the concurrent units will read from a file named "input.txt" and send the contents of that file, one line at a time, to the other concurrent unit, which will print the line it receives to standard output. The printing unit must count the number of lines it prints. After the concurrent unit reading the file sends its last line to the printing unit, the reading unit will request the number of lines printed by the printing unit. The reading unit will then print the number of lines printed by the printing unit. This task requires two-way communication between the concurrent units. All concurrent units must cleanly terminate at the end of the program.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Synchronous concurrency step by step in the C programming language

This is a C program that uses the libco library to implement a simple multithreaded line-counting program. The program consists of two cothreads: a reader cothread and a printer cothread.

The reader cothread is responsible for reading lines of text from a file and passing them to the printer cothread. The reader cothread uses a dynamically-allocated buffer to store the lines of text. The size of the buffer is doubled each time it becomes full.

The printer cothread is responsible for printing the lines of text to the console and counting the number of lines printed.

The main thread of the program starts the reader cothread and then repeatedly switches to the reader cothread to get the next line of text to print. The main thread continues to switch to the reader cothread until the reader cothread has finished reading the file.

Once the reader cothread has finished reading the file, it sets the line buffer to NULL, which causes the main thread to break out of the loop. The main thread then deletes the reader cothread and exits.

Here is a more detailed explanation of the code:

  • The reader_entry function is the entry point for the reader cothread. This function reads lines of text from a file, passes each line to the printer cothread, and reports the number of lines read.
  • The main function is the entry point for the program. This function starts the reader cothread and then repeatedly switches to the reader cothread to get the next line of text to print. The main thread continues to switch to the reader cothread until the reader cothread has finished reading the file.
  • The line structure is a global variable that is shared between the reader cothread and the printer cothread. This structure contains the line buffer, the length of the line, and the capacity of the line buffer.
  • The count variable is a global variable that is shared between the reader cothread and the printer cothread. This variable stores the number of lines that have been printed.

The code demonstrates how to use libco to implement a simple multithreaded program. The program uses two cothreads to read lines of text from a file and print them to the console. The program also counts the number of lines that have been printed.

Source code in the c programming language

#include <stdlib.h>	/* malloc(), realloc(), free() */
#include <stdio.h>	/* fopen(), fgetc(), fwrite(), printf() */

#include <libco.h>	/* co_create(), co_switch() */

void
fail(const char *message) {
	perror(message);
	exit(1);
}

/*
 * These are global variables of this process. All cothreads of this
 * process will share these global variables.
 */
cothread_t reader;
cothread_t printer;
struct {
	char	*buf;	/* Not a C string. No terminating '\0'. */
	size_t	len;	/* Length of line in buffer. */
	size_t	cap;	/* Maximum capacity of buffer. */
} line;
size_t count;		/* Number of lines printed. */

/*
 * The reader cothread reads every line of an input file, passes each
 * line to the printer cothread, and reports the number of lines.
 */
void
reader_entry(void)
{
	FILE *input;
	size_t newcap;
	int c, eof, eol;
	char *newbuf;

	input = fopen("input.txt", "r");
	if (input == NULL)
		fail("fopen");

	line.buf = malloc(line.cap = 4096);  /* New buffer. */
	if (line.buf == NULL)
		fail("malloc");
	line.len = 0;  /* Start with an empty line. */

	do {
		c = fgetc(input);  /* Read next character. */
		if (ferror(input))
			fail("fgetc");

		eof = (c == EOF);
		if (eof) {
			/*
			 * End of file is also end of line,
		`	 * unless the line would be empty.
			 */
			eol = (line.len > 0);
		} else {
			/* Append c to the buffer. */
			if (line.len == line.cap) {
				/* Need a bigger buffer! */
				newcap = line.cap * 2;
				newbuf = realloc(line.buf, newcap);
				if (newbuf == NULL)
					fail("realloc");
				line.buf = newbuf;
				line.cap = newcap;
			}
			line.buf[line.len++] = c;

			/* '\n' is end of line. */
			eol = (c == '\n');
		}

		if (eol) {
			/* Pass our complete line to the printer. */
			co_switch(printer);
			line.len = 0;  /* Destroy our line. */
		}
	} while (!eof);

	free(line.buf);
	line.buf = NULL;  /* Stops a loop in the printer. */

	printf("Printed %zu lines.\n", count);
	co_switch(printer);
}

/*
 * The printer cothread starts the reader cothread, prints every line
 * line from the reader cothread, and counts the number of lines.
 */
int
main()
{
	reader = co_create(4096, reader_entry);
	printer = co_active();
	count = 0;

	for (;;) {
		co_switch(reader);
		if (line.buf == NULL)
			break;

		/* Print this line. Count it. */
		fwrite(line.buf, 1, line.len, stdout);
		count++;
	}

	co_delete(reader);
	return 0;
}


  

You may also check:How to resolve the algorithm Introspection step by step in the Jsish programming language
You may also check:How to resolve the algorithm Wagstaff primes step by step in the Python programming language
You may also check:How to resolve the algorithm Detect division by zero step by step in the PowerShell programming language
You may also check:How to resolve the algorithm Synchronous concurrency step by step in the Rust programming language
You may also check:How to resolve the algorithm Balanced brackets step by step in the Scala programming language