my process doesn't go to the child process - pthreads

I have to take a user input number 'n' in the parent process and then pass it to the child process.The child process then takes 'n' user input values and stores them in an array.It then call a thread and send this array as an argument.The thread sums all the values in the array and send it back to the child process which prints it.
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<pthread.h>
#include<fcntl.h>
void *sum(void *a)
{printf("in thread" );
int * arr=(int *)a;
int i;
int sum=0;
int size=sizeof(arr)/sizeof(arr[0]);
for(i=0;i<size;i++)
{
sum=sum +arr[i];
}
pthread_exit(sum);
}
int main()
{
int pipefd[2];
pid_t childpid;
pthread_t tid;
pipe(pipefd);
int r;
int n;
childpid=fork();
if (0==childpid)
{
printf("in child process" );
close(pipefd[1]);
read(pipefd[0],r,sizeof(int));
close(pipefd[0]);
int *ret;
int a[r];
int i;
for (i = 0; i <r; i++)
{ printf("enter values: ");
scanf("%d",&a[i]);
}
pthread_create(&tid,NULL,sum,(void *)a);
pthread_join(tid,(void *)&ret);
printf("%d",*ret );
}
else
{ printf("in parent process" );
printf("enter a number" );
scanf("%d",&n);
close(pipefd[0]);
write(pipefd[1],n,sizeof(int));
close(pipefd[1]);
}
return 0;
}
I have checked this code a dozen of times and nothing seems to be wrong.The process stops after taking the value of 'n'.The child process never runs.

Both read and write expect to receive the memory address of a buffer to use. You need to take the address of the variables you're trying to fill.
E.g.
write(pipefd[1], &n, sizeof(int));
and
read(pipefd[0], &r, sizeof(int));
By the way, the child process most likely is running. It's just your value for r is coming back as 0. Simple debugging trick: Use fprintf(stderr, "stuff to print"); to check your results at various stages. You can easily verify the child process is running, for example.

Related

Code to locate a specific item in a linked list and remove it

For my Computer Science course we are needing to create 2 functions. One function needs to locate the serial position of the item being searched for (an int in this case) and the index of the previous item. The locateNode function (the function described above) needs to be used within the Remove function as well as other functions already written by the professor in the class. Remove is simply supposed to take the item before the one being removed and make it point to the item that was being pointed to by the removed item. Finally it will take the removed node and push it into an avail list within the same array (essentially there are 2 linked lists in the one array.) My functions are giving me the wrong output and I currently do not know which is wrong or if both functions are wrong.
void SortedList::Remove(ItemType anItem, bool& success)
// IN OUT
{
int previous, position;
success=locateNode(anItem, previous, position);
cerr<<success<<endl;
if (success)
{
int current=list[0].next;
list[previous].next=list[list[previous].next].next;
for (int i=1; i<position; i++)
{
current=list[i].next;
}
PushAvail(current);
}
} // end Remove
bool SortedList::locateNode(
ItemType anItem, int& previous, int& position) const
{
position=1;
previous=0;
int current=list[0].next;
bool isPresent = false;
for (int count=1; count <= size; count++)
{
if (list[current].item >= anItem)
{
if ( list[current].item == anItem)
{
cerr<<"Position "<< position<< endl;
cerr<<"Previous "<< previous<< endl;
isPresent = true;
}
return isPresent;
}
position++;
previous=list[previous].next;
current=list[current].next;
}
return isPresent;
}

pthread_join causing seg fault

As part of a pthreads tutorial exercise I wrote a program to create 10 threads than to join the 10 threads. The program runs and prints the output however it seems that on the first call to pthread_join it causes a segmentation fault. I am not sure why this is occurring. I tried searching on web, however most issues where concerning invalid pointers passed to the function. I am not sure if this is the same issue with my code, as I am not seeing it easily.
if anyone can help me, I certainly would appreciate it :)
code is below:
#include <stdio.h>
#include <pthread.h>
#define NTHREADS 10
void *thread_function(void *arg)
{
int i;
int *coming = (int*) arg;
for(i=0; i<5; i++)
printf("Hello, World (thread %d)\n", *coming);
return NULL;
}
int main(void)
{
int i;
void *exit_status;
int retVal;
pthread_t pthread_array[NTHREADS];
int randVals[10] = {23,5,17,55,9,47,69,12,71,37};
printf("threads are created\n");
for(i=0; i<10; i++)
{
retVal=pthread_create(&pthread_array[i], NULL, thread_function, &randVals[i]);
printf("pthread_create %d retVal=%d\n", i, retVal);
}
printf("threads are joined\n");
for(i=0; i<10; i++)
{
retVal= pthread_join(pthread_array[i], &exit_status);
printf("pthread_join %d retVal=%d and exit_status=%d\n", i, retVal,
*((int *)exit_status));
}
printf("all threads have ended\n");
return 0;
}
This is the problem
printf("pthread_join %d retVal=%d and exit_status=%d\n", i, retVal,
*((int *)exit_status));
your thread function returns NULL, and so this is the value stored in exit_status. So now in your printf you do this
*((int *)exit_status
you are casting this NULL pointer to a int* and then dereferencing it. Dereferencing NULL pointers is not a good idea. See this question for a fuller example of how to use exit_status What does exactly the "status" in pthread_join represent and how to query it
*((int *)exit_status));
If the thread function returns NULL (which it does), this will try to dereference it. Before doing so, you should test exit_status:
pthread_join(...);
if (exit_status != NULL)
/* Safe to use. */

How Lua deal with the stack?

I'm trying Lua and want to know how lua_State working
code and result:
state.c
#include <stdio.h>
#include "lua/src/lua.h"
#include "lua/src/lauxlib.h"
static void stackDump(lua_State *L){
int i;
int top = lua_gettop(L);
for(i = 1; i<= top; i++) {
int t = lua_type(L, i);
switch(t){
case LUA_TSTRING:
printf("'%s'", lua_tostring(L, i));
break;
case LUA_TBOOLEAN:
printf(lua_toboolean(L, i) ?"true":"false");
break;
case LUA_TNUMBER:
printf("%g", lua_tonumber(L, i));
break;
default:
printf("%s", lua_typename(L, t));
break;
}
printf(" ");
}
printf("\n");
}
static int divide(struct lua_State *L){
double a = lua_tonumber(L, 1);
double b = lua_tonumber(L, 2);
printf("%p\n", L);
stackDump(L);
int quot = (int)a / (int)b;
int rem = (int)a % (int)b;
lua_pushnumber(L, quot);
lua_pushnumber(L, rem);
stackDump(L);
printf("---end div---\n");
return 2;
}
int main(void){
struct lua_State *L = lua_open();
lua_pushboolean(L, 1);
lua_pushnumber(L, 10);
lua_pushnil(L);
lua_pushstring(L, "hello");
printf("%p\n", L);
stackDump(L);
lua_register(L, "div", divide);
luaL_dofile(L, "div.lua");
stackDump(L);
lua_close(L);
return 0;
}
div.lua
local c = div(20, 10)
0x100c009e0
true 10 nil 'hello'
---start div---
0x100c009e0
20 10
20 10 2 0
---end div---
true 10 nil 'hello'
I see lua_State in divide is the same with the main one, but they have different data in stack, How this be done ?
I know the best way to understand this is to read source code of Lua , maybe you can tell me where to find the right place.
Think of lua_State as containing the Lua stack, as well as indices delimiting the current visible part of the stack. When you invoke a Lua function, it may look like you have a new stack, but really only the indices have changed. That's the simplified version.
lua_State is defined in lstate.h. I've pulled out the relevant parts for you. stack is the beginning of the big Lua stack containing everything. base is the beginning of the stack for the current function. This is what your function sees as "the stack" when it is executing.
struct lua_State {
/* ... */
StkId top; /* first free slot in the stack */
StkId base; /* base of current function */
/* ... */
StkId stack_last; /* last free slot in the stack */
StkId stack; /* stack base */
/* ... */
};
Programming in Lua, 2nd Edition discusses Lua states in chapter 30: Threads and States. You'll find some good information there. For example, lua_State not only represents a Lua state, but also a thread within that state. Furthermore, all threads have their own stack.
It gets different data the same way anything gets different data: code changes the data inside of the object.
struct Object
{
int val;
};
void more_stuff(Object *the_data)
{
//the_data->val has 5 in it now.
}
void do_stuff(Object *the_data)
{
int old_val = the_data->val;
the_data->val = 5;
more_stuff(the_data);
the_data->val = old_val;
}
int main()
{
Object my_data;
my_data.val = 1;
//my_data.val has 1.
do_stuff(&my_data);
//my_data.val still has 1.
}
When Lua calls a registered C function, it gives it a new stack frame.

what is wrong with following pthread program?

I am not able to execute pthreads program in c. Please tell me what is wrong with the following program. I am neither getting any error nor expected output.
void *worker(void * arg)
{
int i;
int *id=(int *)arg;
printf("Thread %d starts\n", *id );
}
void main(int argc, char **argv)
{
int thrd_no,i,*thrd_id,rank=0;
void *exit_status;
pthread_t *threads;
thrd_no=atoi(argv[1]-1);
thrd_id= malloc(sizeof(int)*(thrd_no));
threads=malloc(sizeof(pthread_t)*(thrd_no));
for(i=0;i<thrd_no;i++)
{
rank=i+1;
thrd_id[i]=pthread_create(&threads[i], NULL, worker, &rank);
}
for(i=0;i<thrd_no;i++)
{
pthread_join(threads[i], &exit_status);
}
}
thrd_no = atoi(argv[1] - 1); likely doesn't do what you intended; the way argv is normally passed into a new process and parsed into a C array, argv[1] - 1 is probably pointing at \0 (specifically, the \0 at the end of argv[0]). (More generally, indexing backwards off the start of a string is rarely correct.) The result is that atoi() will return 0 and no threads will be created. What did you actually intend to do there?
You are passing the same address &rank to each thread, so id and *id is the same for all your worker-s.
You should better allocate on the heap the address you pass to each worker routine.
You might also include <stdint.h and use intptr_t, e.g.
void worker (void* p)
{
intptr_t rk = (intptr_t) p;
/// etc
}
and call
intptr_t rank = i + 1;
thrd_id[i]=pthread_create(&threads[i], NULL, worker, (void*)rank);
You should learn to use a debugger and compile with all warnings and debug information, i.e. gcc -Wall -g (and improve your code till it gets no warnings, then use gdb)
code segment rank=i+1;
thrd_id[i]=pthread_create(&threads[i], NULL, worker, &rank);
will produce race condition.

BCB 6.0 "raised exception class EAccessViolation with message 'Access violation at address'"

I'm newer to C++. I have written some code, but when i run it, there's always this:
raised exception class
EAccessViolation with message 'Access
violation at address'
i don't understand this. Would you like to help me solve it? It's important to me. Really, really thank you!
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <math.h>
#include <conio.h>
#define k 2
#define minoffset 0.5
using namespace std;
struct Point
{
double X;
double Y;
};
vector<Point> dataprocess();
void k_means(vector<Point> points,int N);
double getdistance(Point p1,Point p2)
{ double distance;
distance=sqrt((p1.X-p2.X)*(p1.X-p2.X)+(p1.Y-p2.Y)*(p1.Y-p2.Y));
return distance;
}
int getmindis(Point p,Point means[])
{
int i;
int c;
double dis=getdistance(p,means[0]);
for(i=1;i<k;i++)
{
double term=getdistance(p,means[i]);
if(term<dis)
{
c=i;
dis=term;
}
}
return c;
}
Point getmeans(vector<Point> points)
{
int i;
double sumX,sumY;
Point p;
int M=points.size();
for(i=0;i<M;i++)
{
sumX=points[i].X;
sumY=points[i].Y;
}
p.X=sumX/M;
p.Y=sumY/M;
return p;
}
int main()
{ int N;
vector<Point> stars;
stars=dataprocess();
N=stars.size();
cout<<"the size is:"<<N<<endl;
k_means(stars,N);
getch();
}
vector<Point> dataprocess()
{
int i;
int N;
double x,y;
vector<Point> points;
Point p;
string import_file;
cout<<"input the filename:"<<endl;
cin>>import_file;
ifstream infile(import_file.c_str());
if(!infile)
{
cout<<"read error!"<<endl;
}
else
{
while(infile>>x>>y)
{
p.X=x;
p.Y=y;
points.push_back(p);
}
}
N=points.size();
cout<<"output the file data:"<<endl;
for(i=0;i<N;i++)
{
cout<<"the point"<<i+1<<"is:X="<<points[i].X<<" Y="<<points[i].Y<<endl;
}
return points;
}
void k_means(vector<Point> points,int N)
{
int i;
int j;
int index;
vector<Point> clusters[k];
Point means[k];
Point newmeans[k];
double d,offset=0;
bool flag=1;
cout<<"there will be"<<k<<"clusters,input the original means:"<<endl;
for(i=0;i<k;i++)
{
cout<<"k"<<i+1<<":"<<endl;
cin>>means[i].X>>means[i].Y;
}
while(flag)
{
for(i=0;i<N;i++)
{
index=getmindis(points[i],means);
clusters[index].push_back(points[i]);
}
for(j=0;j<k;j++)
{
newmeans[j]=getmeans(clusters[j]);
offset=getdistance(newmeans[j],means[j]);
}
if(offset>d)
{
d=offset;
}
flag=(minoffset<d)?true:false;
for(i=0;i<k;i++)
{
means[i]=newmeans[i];
clusters[i].clear();
}
}
for(i=0;i<k;i++)
{
cout<<"N"<<i+1<<"="<<clusters[i].size()<<endl;
cout<<"the center of k"<<i+1<<"is:"<<means[i].X<<" "<<means[i].Y<< endl;
}
}
You surely have some algo errors in you code. It is difficult to deal with code without input data, that caused an error, but let's try:
First, lets look at function Point getmeans(vector<Point> points)
it is supposed to evaluate mean coordinates for cluster of points: if you pass an empty cluster to this function it will cause an error:
look here -
int M=points.size()
and here -
for(i=0;i<M;i++)
{
sumX=points[i].X;
sumY=points[i].Y;
}
if your cluster is empty than M will be zero and you loop will iterate 2^31 times (until 32 bit integer overflow) and each time you will try to read values of nonexistent vector items
So, You have to test if you vector is not empty before running main function loop and you have to decide which mean values should be assigned for zero cluster (May be you need an additional flag for empty cluster which will be checked before dealing with cluster's mean values)
Then lets examine function int getmindis(Point p,Point means[]) and, also, a place, where we call it:
index=getmindis(points[i],means); clusters[index].push_back(points[i]);
This function assings points to clusters. cluster number is ruled by c variable. If input point doesn't fit to any cluster, function will return uninitialized variable (holding any possible value) which. then is used as vector index of nonexisting element - possible access violation error
You probably have to initialize c to zero in declaration
Tell us when you will be ready with errors described above and also show us a sample input file (one which causes errors, if all datasets cause errors, show us the smallest one)

Resources