(1) Your biggest problem by far is that you have managed to write a fork bomb. Because you don't exit either child in the fork loop each child is going to fall through and loop around and create their own children until you crash or bring the system down. You want something more like this:
while(i < 2)
{
fork_value = fork();
if(fork_value > 0)
i++;
if(fork_value == 0)
{
if(i==0)
{
printf("0 child is pid %d\n", getpid());
int res;
res = pthread_create(&a_thread,NULL,thread_write,NULL);
res = pthread_join(a_thread,&thread_result1);
exit(0);
}
if(i==1)
{
printf("1 child is pid %d\n", getpid());
int res;
res = pthread_create(&b_thread,NULL,thread_read,NULL);
res = pthread_join(b_thread,&thread_result2);
exit(0);
}
}
}
for (i = 0; i < 2; ++i)
wait(NULL);
Notice the wait
on the children which you neglected.
(2) Always check your return codes. They are like safety belts, a bit of a drag but so helpful when you crash. (Yes, I didn't take my advice here but you should.)
(3) These names are awful.
unsigned short int read;
unsigned short int write;
Stay away from naming variables after system calls. It's confusing and just asking for trouble.
(4) Terminology wise, processes with a common ancestor, like these, are related. The parent can open shared memory and other resources and pass it on to the children. Unrelated processes would, for example, multiple instances of program launched from different terminals. They can share resources but not in the "inherited" way forked processes do.
It's late and didn't get around to looking at what you are doing with the threads and such but this should get you started.