Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[C/C++] read() icm threads cancellen

Pagina: 1
Acties:

  • LauPro
  • Registratie: Augustus 2001
  • Laatst online: 19-11 14:21

LauPro

Prof Mierenneuke®

Topicstarter
Ik heb in thread A hetvolgende:
C:
1
2
3
4
while (read(fd,&event,sizeof(Event_t)) == sizeof(Event_t)) {
  // [..]
}
pthread_exit(0)
en in thread B besluit ik dat het wel welletjes is geweest:
C:
1
2
fd.close();
pthread_join(eventThread,NULL);
Probleem waar ik nu tegenaan loop is dat thread A lekker op die input blijft wachten (komt uit een /dev/*). Mogelijke oplossingen zijn:
• Gebruik maken van non-blocking sockets met sleeps (vrij ranzig).
• In thread A met timed out select() en een isrunning bool gaan werken.
• Controle naar thread B verleggen.

Maar is het niet gewoon mogelijk om die fd duidelijk te maken dat het echt genoeg is geweest?

Inkoopacties - HENK terug! - Megabit
It is a war here, so be a general!


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 19-11 23:43

.oisyn

Moderator Devschuur®

Demotivational Speaker

Als je de socket gewoon eerst closed zou ik het raar vinden als die read() dan alsnog blijft wachten. Overigens gebruik ik zelf doorgaans die tweede optie, maar vaak heb ik dan ook meerdere sockets die allemaal door 1 thread afgehandeld worden, dus dan zit je sowieso al aan de select() (of WaitForMultipleObjects() op win32)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • LauPro
  • Registratie: Augustus 2001
  • Laatst online: 19-11 14:21

LauPro

Prof Mierenneuke®

Topicstarter
Het is dus zo:
• Socket wordt geopend (zie vb1)
• << Dataverkeer >>
• User sluit applicatie
• Thread B wil thread A met socket sluiten (vb2)

Maar ik denk dat ik voor de selectfunctie ga inderdaad.

Inkoopacties - HENK terug! - Megabit
It is a war here, so be a general!


  • LauPro
  • Registratie: Augustus 2001
  • Laatst online: 19-11 14:21

LauPro

Prof Mierenneuke®

Topicstarter
Hmm,

Ik ben even aan de slag gegaan met select() en ik krijg het vermoeden dat je dit niet op files kan gebruiken. Het gaat hier om een device daar een kernelmodule spullen in stopt. Deze haal ik dan userspace er weer uit met read() voorheen.

Echter blijft select niet wachten en gaat gewoon door (ookal is de fd_set geZERO'd e.d.). poll() Was ook niet veel soeps. Wat kan ik het beste hiervoor gebruiken?

Inkoopacties - HENK terug! - Megabit
It is a war here, so be a general!


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

waarschijnlijk zit de fout dan in de kernel module...
Kijk eens of deze alle IO operaties implementeert.

ASSUME makes an ASS out of U and ME


  • LauPro
  • Registratie: Augustus 2001
  • Laatst online: 19-11 14:21

LauPro

Prof Mierenneuke®

Topicstarter
http://doip.laupro.nl/browser/k8055/trunk/k8055.c is de kernelmodule in kwestie. Volgens mij niets geks mee aan de hand.

edit: ik zie idd dat select() niet is geïmplementeerd, ik dacht dat de kernel wel zo slim was om dit zelf te constateren. Even aanpassen dus.

[ Voor 37% gewijzigd door LauPro op 24-02-2008 09:03 ]

Inkoopacties - HENK terug! - Megabit
It is a war here, so be a general!


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-11 18:33
Je kunt een read ook afbreken met een signal. Zie ook http://www.linuxforums.or...upting-blocking-read.html bijvoorbeeld.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • LauPro
  • Registratie: Augustus 2001
  • Laatst online: 19-11 14:21

LauPro

Prof Mierenneuke®

Topicstarter
Ik kom er nog niet echt uit, kernelspace (2.6):
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
static ssize_t k8055_poll(struct file *file, poll_table * wait)
{
        struct usb_k8055 *dev;
        int rc;
        
        dev = (struct usb_k8055 *)file->private_data;
        
        //if (dev->changed == 2) {
        //dev->changed = 1;
    
            poll_wait(file, &dev->wait, wait);
        //}
        
        if (dev->changed != 2) {
                dev->changed = 1;
                rc = wait_event_interruptible(dev->wait, dev->changed == 2);
                /*
                if (rc != 0) {
                return rc;
                }
                */
        }
    
        return POLLIN | POLLRDNORM;
}
Userspace:
C:
1
2
3
4
pfd.fd = fd;
pfd.events = POLLIN;
pfd.revents = 0;
result = poll(&pfd, 1, 1000);
Het probleem is dat poll() geen timeout geeft na 1 seconde, dit lijkt mij te komen omdat wait_event_interruptible() natuurlijk niet gaat zitten wachten, wat zie ik over het hoofd?

Inkoopacties - HENK terug! - Megabit
It is a war here, so be a general!


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-11 18:33
Wordt wait_event_interruptible wel wakker als je een signal krijgt? Anders zou je die voorwaarde moeten meenemen in je wachtconditie.

[edit]
Ik vraag me trouwens nu af of je ueberhaupt wel zou moeten blocken in de poll callback van je device driver.

Alle voorbeelden die ik heb gevonden zetten vlaggen aan de hand van een status die ergens anders is gemaakt ( bv adhv de data van in -en output buffers )


[edit2]
Ik weet niet of je em bij de hand hebt maar volgens mij is dit het naslagwerk voor Linux driver development:
http://lwn.net/Kernel/LDD3/

[ Voor 65% gewijzigd door farlane op 25-02-2008 12:10 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • LauPro
  • Registratie: Augustus 2001
  • Laatst online: 19-11 14:21

LauPro

Prof Mierenneuke®

Topicstarter
Dat naslagwerk heb ik idd gebruikt als leidraad. Ik heb bijv een printk() in die poll functie gezet en als ik dan vanuit userspace select() aanroep dan komt er geen bericht in dmesg, bij poll() wel.

Tja blocken of niet. Ik zie wel dat poll intern kernel device driver poll meerdere keren kan aanroepen. Voor zover ik begreep moet de driver bij poll onmiddelijk wat returnen als er nieuwe data is, en anders wachten totdat. Het probleem is dan dat de userspace timeout volgens mij nergens meer aan bod komt. Of zit dat in poll_wait() verwerkt ofzo.

Ik heb het idee dat die pollfunctie nog meer fops gebruikt ofzo.

Inkoopacties - HENK terug! - Megabit
It is a war here, so be a general!


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-11 18:33
LauPro schreef op maandag 25 februari 2008 @ 15:05:
Het probleem is dan dat de userspace timeout volgens mij nergens meer aan bod komt. Of zit dat in poll_wait() verwerkt ofzo.

Ik heb het idee dat die pollfunctie nog meer fops gebruikt ofzo.
Ik denk inderdaad dat dat het geval is. Het grote voordeel is dat er genoeg voorbeelden te vinden zijn in de kernel source tree :)

Btw, voor zover ik weet komen select en poll bij dezelfde callback uit maar zeker weten doe ik het niet.

[ Voor 10% gewijzigd door farlane op 25-02-2008 15:28 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • LauPro
  • Registratie: Augustus 2001
  • Laatst online: 19-11 14:21

LauPro

Prof Mierenneuke®

Topicstarter
Ok, uiteindelijk opgelost met een kleine check. De kernelspace functie poll_wait() werkt wel goed, alleen je moet wel goed de status returnen, dit omdat deze functie meeredere keren wordt aangeroepen dan de userspace poll(), in mijn geval was dat iets als dit:
C:
1
2
3
4
5
if (dev->changed == 2) { 
    return POLLIN | POLLRDNORM; 
}else{ 
    return 0; 
}
Complete log op http://doip.laupro.nl/changeset/126

[ Voor 189% gewijzigd door LauPro op 26-02-2008 08:57 ]

Inkoopacties - HENK terug! - Megabit
It is a war here, so be a general!

Pagina: 1