LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices


Reply
  Search this Thread
Old 01-07-2014, 01:18 AM   #1
p l soujanya
LQ Newbie
 
Registered: May 2010
Posts: 3

Rep: Reputation: 0
pthreads and signals


i have main thread in which i shud have 4 different threads
1. receive thread which receives msg id
2. process thread which process the received msg id
3. display thread which displays the status in the gui

presently i have written the program with two threads.
but am getting segmentation fault
can any body tell me how to handle this
i was asked to do this with pthread_kill

#include<iostream>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include "structures.h"
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <arpa/inet.h>


#include <fcntl.h>
#include <signal.h>
#include <check.h>


#define MAX_DATA_SIZE 512

using namespace std;

pthread_t receive_thread,process_thread;


void sig_handler(int sig)
{
cout<<"caught signal"<<sig<<endl;
}
void *receive_data(void *)
{

cout<<"Receive thread is running"<<endl;
pthread_kill(process_thread,SIGUSR1);

return 0;
}
void *process_data(void*)
{

cout<<"process thread is running"<<endl;

struct sigaction sa;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = sig_handler;
sigaction(SIGUSR1,&sa,NULL);

pthread_exit(0);
return 0;
}
int main(void)
{
int receive_status,process_status;

receive_status=pthread_create(&receive_thread,NULL,receive_data,NULL); // Create Thread
pthread_join(receive_thread,NULL); // Parent waits for

process_status = pthread_create (&process_thread,NULL,process_data,NULL);
//pthread_join(process_thread,NULL);

return 0;
}
 
Old 01-07-2014, 06:01 PM   #2
Pearlseattle
Member
 
Registered: Aug 2007
Location: Zurich, Switzerland
Distribution: Gentoo
Posts: 999

Rep: Reputation: 142Reputation: 142
Hi


The...
Quote:
receive_status=pthread_create(&receive_thread,NULL,receive_data,NULL); // Create Thread
...will start the thread processed by the function "receive_data" putting its handle into the variable "receive_thread" which will...
Quote:
pthread_kill(process_thread,SIGUSR1);
...kill the other thread called "process_data" which you haven't started yet because of the line...
Quote:
pthread_join(receive_thread,NULL); // Parent waits for
...which is waiting for the thread "receive_data" to terminate => it probably goes into segfault when it tries to kill the not-existing thread processed by the function "process_data" (using the handle "process_thread").

You're near to what you want to do but you have to re-read how to handle threads and rethink how to handle them.

I'm not very good with multithreading but here is what I know right now:
1):
you don't usually "kill" threads, but make them exit by ending their processing sequence using "normal" code => if you have e.g. a thread doing just 1+1, that thread will terminate spontanously as soon as that operation is done.
2)
To terminate a thread that is looping forever you put in (e.g.) your "while"-loop a variable which will be changed by the main thread (or some other thread) when the thread has to exit.
To do this you'll create a variable OR structure OR class OR anything in the >main< thread and give its memory address as fourth parameter to the function which creates the thread (e.g. "int myInt; pthread_create (&process_thread,NULL,process_data,&myInt); ") and use that pointer in the thread-function which will continuously check its status to know if it has to end the loop or not (you'll have to put a "sleep()" call to avoid using 100% CPU).
3):
Most likely you'll have both (or more) threads managing the same data (e.g. one prepares the data, the other one processes it) => to avoid that one or multiple threads write/read that data while others are writing/reading it (major confusion => segfault or other funny behaviours), you'll have to use mutexes/semaphores to coordinate all threads.

Try again, but use first of all only 1 thread and make it exit without you having to kill it but using only the normal keyboard input => once that works add a second thread and coordinate them and the main thread using mutexes/semaphores.

Cheers
 
Old 01-14-2014, 11:40 PM   #3
p l soujanya
LQ Newbie
 
Registered: May 2010
Posts: 3

Original Poster
Rep: Reputation: 0
pthreads and signals

thank u sir
i have tried it and it is starting my second thread which is process_thread
but sir my caught signal output is coming for only once when my first message is received
when am receiving second message my second thread is not giving caught signal output
can u tell me where am wrong and how to correct it

my code is follows:


#include<iostream>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include "structures.h"
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <arpa/inet.h>


#include <fcntl.h>
#include <signal.h>
#include <check.h>


#define MAX_DATA_SIZE 512

using namespace std;

struct Message
{
int message_id;
};
struct Message msg;
pthread_t p;
void * r_data(void *);
void * p_data(void *);
static void usr1_handler(int signo);
int main()
{
pthread_t r;
sigset_t sigmask;
struct sigaction action;

sigfillset(&sigmask);
pthread_sigmask(SIG_BLOCK, &sigmask,(sigset_t *)0);

action.sa_flags = 0;
action.sa_handler = usr1_handler;
sigaction(SIGUSR1, &action, (struct sigaction *)0);

pthread_create(&r,NULL,r_data,NULL);
//
pthread_create(&p,NULL,p_data,NULL);



struct sigaction action;



action.sa_flags = 0;
action.sa_handler = usr1_handler;
sigaction(SIGUSR1, &action, (struct sigaction *)0);
//pthread_join(r,NULL);
//pthread_join(p,NULL);

cout<<"main program"<<endl;
pthread_exit((void *)NULL);
return 0;
}
void *r_data(void *)
{

cout<<"first thread"<<endl;
printf("Hello\n");
int fd;

printf("Hello2\n");
struct sockaddr_in servaddr, cliaddr;

// void **status;

fd = socket(AF_INET,SOCK_DGRAM,0);
printf("Hello3\n");

if(fd <0)
cout<<"Socket creation Failed"<<endl;

servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("10.66.48.11"); //server ip addr
// servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); //server ip addr
servaddr.sin_port = htons(12007); //server poet no.
printf("Hello4\n");
if(bind(fd,(const struct sockaddr *)&servaddr,sizeof(servaddr))<0)
cout<<"BIND FAILED"<<endl;
unsigned char buffer[MAX_DATA_SIZE];

socklen_t len=sizeof(cliaddr);
fcntl(fd,F_SETFL,O_NONBLOCK);

printf("Hello5\n");

for(;
{
sleep(3);
int n= recvfrom(fd,buffer,sizeof(buffer),0,(struct sockaddr *)&cliaddr,&len);

memcpy(&msg,buffer,sizeof(msg));

printf("Hello7\n");
cout<<"Received : bytes"<<n<<" "<<msg.message_id<<endl;
if(msg.message_id!=0)
{

pthread_kill(p, SIGUSR1);


}
}
pthread_exit((void *)NULL);
}
void *p_data(void*)
{

int sig;
sigset_t sigmask;
sigemptyset(&sigmask);
sigaddset(&sigmask, SIGUSR1);
pthread_sigmask(SIG_UNBLOCK, &sigmask, (sigset_t *)0);
sigwait(&sigmask, &sig);
switch(sig)
{
case SIGUSR1:
usr1_handler(sig);
break;
default:
break;
}
}
void usr1_handler(int sig)
{
cout<<"caught signal"<<endl;

}
 
Old 01-16-2014, 02:48 AM   #4
p l soujanya
LQ Newbie
 
Registered: May 2010
Posts: 3

Original Poster
Rep: Reputation: 0
signals and threads

thank u sir
i have tried it and it is starting my second thread which is process_thread
but sir my caught signal output is coming for only once when my first message is received
when am receiving second message my second thread is not giving caught signal output
can u tell me where am wrong and how to correct it

my code is follows:


#include<iostream>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include "structures.h"
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <arpa/inet.h>


#include <fcntl.h>
#include <signal.h>
#include <check.h>


#define MAX_DATA_SIZE 512

using namespace std;

struct Message
{
int message_id;
};
struct Message msg;
pthread_t p;
void * r_data(void *);
void * p_data(void *);
static void usr1_handler(int signo);
int main()
{
pthread_t r;
sigset_t sigmask;
struct sigaction action;

sigfillset(&sigmask);
pthread_sigmask(SIG_BLOCK, &sigmask,(sigset_t *)0);

action.sa_flags = 0;
action.sa_handler = usr1_handler;
sigaction(SIGUSR1, &action, (struct sigaction *)0);

pthread_create(&r,NULL,r_data,NULL);
//
pthread_create(&p,NULL,p_data,NULL);



struct sigaction action;



action.sa_flags = 0;
action.sa_handler = usr1_handler;
sigaction(SIGUSR1, &action, (struct sigaction *)0);
//pthread_join(r,NULL);
//pthread_join(p,NULL);

cout<<"main program"<<endl;
pthread_exit((void *)NULL);
return 0;
}
void *r_data(void *)
{

cout<<"first thread"<<endl;
printf("Hello\n");
int fd;

printf("Hello2\n");
struct sockaddr_in servaddr, cliaddr;

// void **status;

fd = socket(AF_INET,SOCK_DGRAM,0);
printf("Hello3\n");

if(fd <0)
cout<<"Socket creation Failed"<<endl;

servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("10.66.48.11"); //server ip addr
// servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); //server ip addr
servaddr.sin_port = htons(12007); //server poet no.
printf("Hello4\n");
if(bind(fd,(const struct sockaddr *)&servaddr,sizeof(servaddr))<0)
cout<<"BIND FAILED"<<endl;
unsigned char buffer[MAX_DATA_SIZE];

socklen_t len=sizeof(cliaddr);
fcntl(fd,F_SETFL,O_NONBLOCK);

printf("Hello5\n");

for(;
{
sleep(3);
int n= recvfrom(fd,buffer,sizeof(buffer),0,(struct sockaddr *)&cliaddr,&len);

memcpy(&msg,buffer,sizeof(msg));

printf("Hello7\n");
cout<<"Received : bytes"<<n<<" "<<msg.message_id<<endl;
if(msg.message_id!=0)
{

pthread_kill(p, SIGUSR1);


}
}
pthread_exit((void *)NULL);
}
void *p_data(void*)
{

int sig;
sigset_t sigmask;
sigemptyset(&sigmask);
sigaddset(&sigmask, SIGUSR1);
pthread_sigmask(SIG_UNBLOCK, &sigmask, (sigset_t *)0);
sigwait(&sigmask, &sig);
switch(sig)
{
case SIGUSR1:
usr1_handler(sig);
break;
default:
break;
}
}
void usr1_handler(int sig)
{
cout<<"caught signal"<<endl;

}
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] [Pthreads]Usage of Conditions Variables with Pthreads Aquarius_Girl Programming 2 01-14-2013 05:40 AM
pthreads manaila Linux - Newbie 1 07-01-2011 11:59 AM
Pthreads in c++ brevleq Programming 11 11-14-2009 04:52 AM
Does pthreads share signals? PuppetZ Programming 2 03-05-2007 09:25 AM
pthreads socket9001 Programming 2 12-29-2003 12:23 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - General

All times are GMT -5. The time now is 03:42 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration