How do I write a string to a 2D array in C? - arrays

So I am working on a multi-threading program with 4 threads. For thread1 I am grabbing input from stdin and then putting it into buffer1, thread2 then reads from buffer1, modifies it, then puts it in buffer2 for thread3 to read, and so on....
After I have read from buffer1 (in my thread2 function), I have successfully altered the data, now I want to put it in buffer2, but I am getting the error of "expression must be a modifiable lvalue". Does anyone know why??
My thread 2 function is below and the error is appearing in buffer2[write2] = updatedStr;
void *line_separator_thread(void *args)
{
// Consuming from buffer 1 and producing to buffer 2
int haveStop = 0;
while (1)
{
// Snag the mutext for a read
pthread_mutex_lock(&mutex1);
// Release the mutex and block on the condition
pthread_cond_wait(&readyBuffer1, &mutex1);
// Process all unread slots from the buffer1 queue
while (buffer1[read1][0] != -1) // Look for no sentinal value
{
haveStop = haveStopInText(buffer1[read1]);
if (haveStop)
break;
// ***If no break, then read from buffer1, and modify \n to be a space?
// str_replace(orig, replace, with)
char *updatedStr = str_replace(buffer1[read1], "\n", " ");
printf("UPDATED STRING: %s\n", updatedStr);
read1 = (read1 + 1) % 5;
// ***Put the updated string in buffer 2?
pthread_mutex_lock(&mutex2);
buffer2[write2] = updatedStr; //ERROR IS HERE!!!
// ***Need to change buffer1[read1][0] So that it doesn't keep looping?
}
// ***Unlock the mutex here? Or outside of the while loop?
pthread_mutex_unlock(&mutex1);
}
return NULL;
Buffer variables and read/write variables are below
char buffer1[5][1000]; //inputThread + lineSeparatorThread
char buffer2[5][1000];
char buffer3[5][1000];
// Set up variables to let the threads know where is it safe to read from and write to
int write1 = 0;
int read1 = 0;
int write2 = 0;
int read2 = 0;
int write3 = 0;
int read3 = 0;
And lastly, below is in my main function where I am creating the 4 threads
pthread_create(&outputThread, &attr, output_thread, NULL);
usleep(100); // Force the program to allow output thread to actually come up and pend on readyBuffer 3 first
pthread_create(&plusSignThread, &attr, plus_sign_thread, NULL);
usleep(100); // Force the program to allow plus_sign_thread thread to actually come up first
pthread_create(&lineSeparatorThread, &attr, line_separator_thread, NULL);
usleep(100); // Force the program to allow line_separator_thread thread to actually come up first
pthread_create(&inputThread, &attr, input_thread, NULL);
pthread_join(inputThread, NULL);
pthread_join(lineSeparatorThread, NULL);
pthread_join(plusSignThread, NULL);
pthread_join(outputThread, NULL);

Related

Thread don't terminate their job

I am writing a concurrent C program where I want to wait for all threads to finish in the main().
Based on this solution, I wrote the following code in main():
// Create threads
pthread_t cid[num_mappers];
int t_iter;
for (t_iter = 0; t_iter < num_mappers; t_iter++){
pthread_create(&(cid[t_iter]), NULL, &map_consumer, NULL);
}
// Wait for all threads to finish
for (t_iter = 0; t_iter < num_mappers; t_iter++){
printf("Joining %d\n", t_iter);
int result = pthread_join(cid[t_iter], NULL);
}
printf("Done mapping.\n");
The function passed into threads is defined as:
// Consumer function for mapping phase
void *map_consumer(void *arg){
while (1){
pthread_mutex_lock(&g_lock);
if (g_cur >= g_numfull){
// No works to do, just quit
return NULL;
}
// Get the file name
char *filename = g_job_queue[g_cur];
g_cur++;
pthread_mutex_unlock(&g_lock);
// Do the mapping
printf("%s\n", filename);
g_map(filename);
}
}
The threads are all successfully created and executed, but the join loop will never finish if num_mappers >= 2.
You return without unlocking the mutex:
pthread_mutex_lock(&g_lock);
if (g_cur >= g_numfull){
// No works to do, just quit
return NULL; <-- mutex is still locked here
}
// Get the file name
char *filename = g_job_queue[g_cur];
g_cur++;
pthread_mutex_unlock(&g_lock);
So only one thread ever returns and ends - the first one, but since it never unlocks the mutex, the other threads remain blocked.
You need something more like
pthread_mutex_lock(&g_lock);
if (g_cur >= g_numfull){
// No works to do, just quit
pthread_mutex_unlock(&g_lock);
return NULL;
}
// Get the file name
char *filename = g_job_queue[g_cur];
g_cur++;
pthread_mutex_unlock(&g_lock);

pthread_mutex_lock works only with sleep

I pass a struct in pthread_create which contains a char* and I lock the main and the thread with mutexes so I can protect this string because when the second thread will be created the string will change and the first thread will use the second string and not the first. Here is the code:
main.c
while( th_num < th_size )
{
pthread_mutex_lock(&lock);
received = 0;
/* Read the desired readable size */
if( read(newsock, &size, sizeof(size)) < 0 )
{ perror("Read"); exit(1); }
/* Read all data */
while( received < size )
{
if( (nread = read(newsock, buffer + received, size - received)) < 0 )
{ perror("Read"); exit(1); }
received += nread;
}
printf("Received string: %s\n",buffer);
Q->receiver = (char*) malloc(sizeof(char)*strlen(buffer)+1);
strncpy(Q->receiver, buffer, strlen(buffer)+1);
if( (err = pthread_create(&thread_server[th_num], NULL, thread_start, (void*) Q)) == true )
{ show_error("pthread_create", err); }
/* -------------------------------------------------- */
th_num++;
pthread_mutex_unlock(&lock);
usleep(500);
}
pthread_server.c
pthread_mutex_lock(&lock);
/*
do some stuff here
*/
pthread_mutex_unlock(&lock);
The program works fine but the problem is that it only works if I put usleep(500). My guess is that the thread cant lock the mutex in time so it needs sleep to do this right. Is there a way to do it without usleep()?
Assuming I don't understand why you need to call pthread_create(); in a mutual exclusion portion of code, your problems is:
you use threads but the flow of your program is approaching to be sequential because of the large mutual exclusion portion of code.
Let X a generic thread in your program.
Without the usleep(500); when the X thread finish it releases the mutex with pthread_mutex_unlock(&lock); but afterwards the thread X reacquires the lock so no one else can access in the mutual exclusion portion of code.
Now I don't know what your shared data is, so I can only suggest you:
1) Reduce the mutual exclusion portion of code, only use it when you access to a shared data;
2) Rethink about your program structure.

How to get two pthread threads to respond to each others' wait and signal conditions?

I'm having a bit of trouble getting a basic two-thread arrangement working.
I am reading a chunk of bytes into memory from stdin in one "producer" thread, and processing those bytes in a second "consumer" thread, once those bytes are available. Once the bytes are consumed, the consumer thread goes back to being dormant and the producer thread gets running again.
I am using pthread_cond_wait() and pthread_cond_signal() to have the two threads communicate to each other that data are produced or consumed.
Here is the code for the two threads:
void * produce_bytes(void *t_data)
{
pthread_data_t *d = (pthread_data_t *)t_data;
do {
pthread_mutex_lock(&d->input_lock);
d->n_bytes = fread(d->in_buf, sizeof(unsigned char), BUF_LENGTH_VALUE, stdin);
if (d->n_bytes > 0) {
fprintf(stdout, "PRODUCER ...signaling consumer...\n");
pthread_cond_signal(&d->input_cond);
fprintf(stdout, "PRODUCER ...consumer signaled...\n");
}
pthread_mutex_unlock(&d->input_lock);
} while (d->n_bytes > 0);
return NULL;
}
void * consume_bytes(void *t_data)
{
pthread_data_t *d = (pthread_data_t *)t_data;
pthread_mutex_lock(&d->input_lock);
while (d->n_bytes == 0)
pthread_cond_wait(&d->input_cond, &d->input_lock);
fprintf(stdout, "CONSUMER ...consuming chunk...\n");
d->n_bytes = 0;
fprintf(stdout, "CONSUMER ...chunk consumed...\n");
pthread_mutex_unlock(&d->input_lock);
}
The pthread_data_t is a struct I use to keep track of state:
typedef struct {
pthread_mutex_t input_lock;
pthread_cond_t input_cond;
unsigned char in_buf[BUF_LENGTH_VALUE];
size_t n_bytes;
} pthread_data_t;
I configure variables in my main() function; here is the relevant excerpt:
pthread_t producer_thread = NULL;
pthread_t consumer_thread = NULL;
pthread_data_t *thread_data = NULL;
thread_data = malloc(sizeof(pthread_data_t));
thread_data->n_bytes = 0;
pthread_mutex_init(&(thread_data->input_lock), NULL);
pthread_cond_init(&(thread_data->input_cond), NULL);
pthread_create(&producer_thread, NULL, produce_bytes, (void *) thread_data);
pthread_create(&consumer_thread, NULL, consume_bytes, (void *) thread_data);
pthread_join(producer_thread, NULL);
pthread_join(consumer_thread, NULL);
When I run this, produce_bytes() signals consume_bytes() successfully on the first iteration, but on the second and subsequent iterations, a signal is sent to consume_bytes() and it never gets heard, so the consumer function never gets run again:
PRODUCER ...signaling consumer...
PRODUCER ...consumer signaled...
CONSUMER ...consuming chunk...
CONSUMER ...chunk consumed...
PRODUCER ...signaling consumer...
PRODUCER ...consumer signaled...
PRODUCER ...signaling consumer...
PRODUCER ...consumer signaled...
PRODUCER ...signaling consumer...
PRODUCER ...consumer signaled...
...
I am using the tutorial here as the basis for what I'm trying to do. What I am doing wrong?
There are a few issues with that code:
produce_bytes locks the mutex for the duration of the blocking call to fread. A general rule of thumb for responsive applications is to lock the mutex for as short periods as possible. You may like to read the input into a temporary buffer first, then lock the mutex and copy the data to the buffer shared between threads. Same applies to consume_bytes which holds the mutex while calling fprintf which can block.
produce_bytes in while(d->n_bytes > 0) does not hold the mutex, which is a race condition because consume_bytes assigns a new value to d->n_bytes. Assuming you would like to exit that loop when fread returns 0 (EOF), you need to copy the return value of fread into a local variable not shared between threads and use that as the condition in while(read_bytes > 0)
consume_bytes does not have any loop around it so that it returns after the first condition variable notification. You probably would like to wrap it into a while loop and exit only when EOF (0 bytes) have been read.
Here is a working example which addresses Maxim's point 2 and 3, but not 1 because that is necessary for responsiveness but not strictly for correctness.
Note that I have not implemented a means for the producer to signal EOF to the consumer, so the consumer will never exit.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define BUF_LENGTH_VALUE 100
typedef struct {
pthread_mutex_t input_lock;
pthread_cond_t input_cond;
unsigned char in_buf[BUF_LENGTH_VALUE];
size_t n_bytes;
} pthread_data_t;
void * produce_bytes(void *t_data)
{
pthread_data_t *d = (pthread_data_t *)t_data;
size_t local_byte_count = 0;
do {
pthread_mutex_lock(&d->input_lock);
local_byte_count = fread(d->in_buf, sizeof(unsigned char),
BUF_LENGTH_VALUE, stdin);
d->n_bytes += local_byte_count;
if (d->n_bytes > 0) {
fprintf(stdout, "PRODUCER ...signaling consumer...\n");
pthread_cond_signal(&d->input_cond);
fprintf(stdout, "PRODUCER ...consumer signaled...\n");
}
pthread_mutex_unlock(&d->input_lock);
// This is added to slow down the producer so that we can observe
// multiple consumptions.
sleep(1);
} while (local_byte_count > 0);
return NULL;
}
void * consume_bytes(void *t_data)
{
pthread_data_t *d = (pthread_data_t *)t_data;
while (1) {
pthread_mutex_lock(&d->input_lock);
while (d->n_bytes == 0) {
fprintf(stdout, "CONSUMER entering wait \n");
pthread_cond_wait(&d->input_cond, &d->input_lock);
}
fprintf(stdout, "CONSUMER ...consuming chunk...\n");
d->n_bytes = 0;
fprintf(stdout, "CONSUMER ...chunk consumed...\n");
pthread_mutex_unlock(&d->input_lock);
fflush(stdout);
}
}
int main(){
pthread_t producer_thread = NULL;
pthread_t consumer_thread = NULL;
pthread_data_t *thread_data = NULL;
thread_data = malloc(sizeof(pthread_data_t));
thread_data->n_bytes = 0;
pthread_mutex_init(&(thread_data->input_lock), NULL);
pthread_cond_init(&(thread_data->input_cond), NULL);
pthread_create(&producer_thread, NULL, produce_bytes, (void *) thread_data);
pthread_create(&consumer_thread, NULL, consume_bytes, (void *) thread_data);
pthread_join(producer_thread, NULL);
pthread_join(consumer_thread, NULL);
}

Producer Consumer Multithreaded printf issues

I have written a program which simulates the producer consumer problem and I am running into a couple of issues. This was written using Win32 API.
I am using two semaphores full and empty to perform the counting for the buffer where items are stored. There is a mutex as well to control access to the critical section. I have two functions: one creates an item based on a simple calculation: threads * 1000000 + count, while the other consumes it.
The buffer has 10 spaces in it however the program should hopefully be able to work for different number of spaces and threads. The Producer thread goes through the buffer then starts over until the semaphore counts up to 10. I am running into two problems that I can't seem to find a solution too nor do I get many details in the debugger.
1) The commented part which has the printf() function crashes the thread every single time. Nothing ever gets printed to console. I have tried using just a string as well with no other variables being outputted. No success. I found documentation that printf() can run into trouble when used in a multithreaded environment however in this case it is within the critical section and it crashes on the first try. How can I print that information to console?
2) When I remove the print statements and run the code the threads still crash at different points every time. I can't figure out why. The producer thread is supposed to wait for the empty semaphore and the mutex, put the item in, then increase the count for the full semaphore (signifying an item has been added). When it reaches 10 it should stop. The Consumer thread waits for the full semaphore and the mutex, removes an item, then increases the count for the empty semaphore. Is there something in the way I've written it that is causing these thread exits?
This is what I get:
The program '[5348] OperatingSystem.exe' has exited with code 0 (0x0).
#include<stdio.h>
#include<windows.h>
#include<ctype.h>
#include<tchar.h>
#include<strsafe.h>
#include<conio.h>
#include<time.h>
#define threads 1
#define MAX 10
typedef struct objects {
HANDLE empty;
HANDLE full;
HANDLE mutex;
int buffer[10];
};
struct objects data;
DWORD WINAPI Producers(LPVOID lpParam){
int count = 0;
int item;
while (TRUE){
if (data.buffer[count] == 0){
WaitForSingleObject(data.empty, INFINITE);
WaitForSingleObject(data.mutex, INFINITE);
item = threads * 1000000 + count;
data.buffer[count] = item;
//printf("Producer has produced: %d", item);
ReleaseMutex(data.mutex);
ReleaseSemaphore(data.full, 1, NULL);
}
count++;
if (count == 10){ count = 0; }
};
}
DWORD WINAPI Consumers(LPVOID lpParam){
int count = 0;
while (TRUE){
if (data.buffer[count] != 0){
WaitForSingleObject(data.full, INFINITE);
WaitForSingleObject(data.mutex, INFINITE);
//printf("Consumer has consummed: %d", data.buffer[count]);
data.buffer[count] = 0;
ReleaseMutex(data.mutex);
ReleaseSemaphore(data.empty, 1, NULL);
}
count++;
if (count == 10){ count = 0; }
};
}
int main(int argc, char *argv[]) {
struct objects data;
LONG initialCount = 0;
LONG maxCount = 10;
data.empty = CreateSemaphore(NULL, maxCount, maxCount, NULL);
data.full = CreateSemaphore(NULL, initialCount, maxCount, NULL);
data.mutex = CreateMutex(NULL, FALSE, NULL);
DWORD ConsumerId[threads];
HANDLE ConsumerThread[threads];
DWORD ProducerId[threads];
HANDLE ProducerThread[threads];
for (int i = 0; i < threads; i++){
ProducerThread[i] = CreateThread(
NULL,
0,
Producers,
NULL,
0,
&ProducerId[i]);
ConsumerThread[i] = CreateThread(
NULL,
0,
Consumers,
NULL,
0,
&ConsumerId[i]);
}
}

threads have the same id

I learn threads. I have read that thread terminates after it is out of a function (that is passed as parameter to pthread_create function).
So I create threads in the loop, they are executed and afterwards they are terminated.
(sorry for some long code)
But when I call a function pthread_create, new threads get the same ids. Why?
struct data {
FILE *f;
};
void *read_line_of_file(void *gdata) {
pthread_mutex_lock(&g_count_mutex); // only one thread can work with file,
//doing so we block other threads from accessing it
data *ldata = (data *) gdata;
char line[80];
int ret_val =fscanf(ldata->f,"%s",line);
pthread_mutex_unlock(&g_count_mutex); // allow other threads to access it
if (ret_val != EOF)
printf("%s %lu\n ", line, pthread_self());
// some time consuming operations, while they are being executed by one thread,
// other threads are not influenced by it (if there are executed on different cores)
volatile int a=8;
for (int i=0;i <10000;i++ )
for (int i=0;i <10000;i++ ) {
a=a/7+i;
}
if (ret_val == EOF) // here thread ends
pthread_exit((void *)1);
pthread_exit((void *)0);
}
int main() {
int kNumber_of_threads=3, val=0;
pthread_t threads[kNumber_of_threads];
int ret_val_from_thread=0;
data mydata;
mydata.f = fopen("data.txt","r");
if ( mydata.f == NULL) {
printf("file is not found\n");
return 0;
}
for( ; val != 1 ;) {
// THIS IS THAT PLACE, IDs are the same (according to the number of processes),
// I expected them to be changing..
for(int i=0; i<kNumber_of_threads; i++) {
pthread_create(&threads[i],NULL,read_line_of_file, &mydata);
}
for(int i=0; i<kNumber_of_threads; i++) {
pthread_join(threads[i], (void **) &ret_val_from_thread);
if (ret_val_from_thread != 0)
val = ret_val_from_thread;
}
printf(" next %d\n",val);
}
printf("work is finished\n");
fclose(mydata.f);
return 0;
}
as result, I see that id of threads are not being changed:
I wonder, are new threads really created?
Thanks in advance!
Thread IDs are only guaranteed to be different among currently running threads. If you destroy a thread and create a new one, it may well be created with a previously used thread ID.

Resources