I try to syncronize threads with condition variables to output mandelbrot but i get wrong mandelbort.
The functions output_mandel_line and compute_mandel_line are given and are correct. I made the
void *function() and int main(). I suspect the issue is with the if statement inside the mutex_lock. I tried different if or while statement but i couldn't fix it. Perhaps there issue also on how i use the cond_wait ,cond_broadcast.
int nthreads;
pthread_cond_t cond;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
/***************************
* Compile-time parameters *
***************************/
/*
* Output at the terminal is is x_chars wide by y_chars long
*/
int y_chars = 50;
int x_chars = 90;
/*
* The part of the complex plane to be drawn:
* upper left corner is (xmin, ymax), lower right corner is (xmax, ymin)
*/
double xmin = -1.8,
xmax = 1.0;
double ymin = -1.0,
ymax = 1.0;
/*
* Every character in the final output is
* xstep x ystep units wide on the complex plane.
*/
double xstep;
double ystep;
/*
* This function computes a line of output
* as an array of x_char color values.
*/
void
compute_mandel_line(int line, int color_val[])
{
}
/*
* This function outputs an array of x_char color values
* to a 256-color xterm.
*/
void
output_mandel_line(int fd, int color_val[])
{
}
/* Now that the line is done, output a newline character */
if (write(fd, &newline, 1) != 1) {
perror("compute_and_output_mandel_line: write newline");
exit(1);
}
}
void *
function(void *arg)
{
int *number = (int *) arg,
line;
int color_val[x_chars];
for (line = *number; line < y_chars; line += nthreads) {
compute_mandel_line(line, color_val);
pthread_mutex_lock(&mutex);
output_mandel_line(1, color_val);
pthread_cond_signal(&cond);
if (line + nthreads < y_chars) {
pthread_cond_wait(&cond, &mutex);
}
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
free(arg);
return NULL;
}
int
main(int argc, char **argv)
{
if (argc != 2) {
fprintf(stderr, "Wrong format");
exit(1);
}
nthreads = atoi(argv[1]);
int i;
pthread_t t[nthreads];
// pthread_t *t =(pthread_t*)malloc(nthreads * sizeof(pthread_t));
// ret =(pthread_cond_t*)malloc(nthreads * sizeof(pthread_cond_t));
int ret;
xstep = (xmax - xmin) / x_chars;
ystep = (ymax - ymin) / y_chars;
pthread_cond_init(&cond, NULL);
pthread_mutex_init(&mutex, NULL);
for (i = 0; i < nthreads; i++) {
int *a = malloc(sizeof(int));
*a = i;
ret = pthread_create(&t[i], NULL, function, a);
if (ret) {
perror_pthread(ret, "error");
exit(1);
}
}
for (i = 0; i < nthreads; i++) {
ret = pthread_join(t[i], NULL);
if (ret) {
perror_pthread(ret, "error");
exit(1);
}
}
pthread_cond_destroy(&cond);
pthread_mutex_destroy(&mutex);
/*
* Allocate memory for threads and semaphores
* draw the Mandelbrot Set, one line at a time.
* Output is sent to file descriptor '1', i.e., standard output.
*/
reset_xterm_color(1);
return 0;
}
I tried changing the if statement and the condition variable order of cond_wait , cond_signal
pthread_cond_signalwhile holding the lock and immediately dopthread_cond_waiton the same condition variable, the receiver will never get released because the sender will get the signal. And, you have to loop the condition vaiable(s):pthread_mutex_lock(&mutex); while (line + nthreads < y_chars) pthread_cond_wait(&cond,&mutex); pthread_mutex_unlock(&mutex);And, I'm not totally sure, but you may have to release the mutex before doing the signal.kill()function.) Only a thread already blocked inpthread_cond_wait()can be awoken by a call topthread_cond_signal(). No thread can break itself out of its ownpthread_cond_wait(), no matter what mutex it holds or when.