Da es unter Linux keine Suspend Thread-ähnliche API gab, versuchen Sie, den Thread mit Mutex anzuhalten / fortzusetzen.
Zur Zeit habe ich es zweimal implementiert, aber ich habe darauf hingewiesen, dass ich nicht zu viel Wissen über die Implementierung der OS-API habe, also habe ich es zweimal gegessen, also bin ich verrückt danach, also frage ich mich, ob es das dritte Mal ist, um ehrlich zu sein, oder ob es zwei Mal gibt.
Punkte von @drab
Punkte, auf die @ angel_p_57 hinweisen muss
Bei der Implementierung der Nachrichtenverarbeitung oder ähnlichem Wenn Sie die Nachrichten in der Warteschlange kontinuierlich verarbeiten möchten, nachdem Sie sie in die Warteschlange gestellt haben (kurz: asynchrone Verarbeitung, z. B. Senden an die NW-Seite).
Ich möchte den Thread an einem bestimmten Punkt anhalten, da dies eine Verschwendung von Ressourcen ist, die sich verschwenderisch wiederholen, wenn keine Nachricht vorhanden ist. Kurz gesagt, ich möchte auf die Veranstaltung warten.
Hinweis: Die Verwendung von pthread_cond_wait in Code, der etwas mit einem Tastendruckereignis tut, ist wahrscheinlich nicht möglich Was ich tun möchte: Ich möchte auf ein Ereignis warten.
Aus.
~~ Ein Memo zum Anhalten mit Mutex in einem solchen Fall. ~~
~~ ** 2017/04/17 Ich habe es mit der richtigen Implementierungsmethode entsprechend der genannten Angelegenheit geschrieben. (Siehe unten im Artikel) ** ~~ ** 21.04.2017 erneut korrigiert **
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <pthread.h>
#include <unistd.h>
#include <stdarg.h>
#include<stdint.h>
#include<assert.h>
//Legen Sie eine Schnur auf die Konsole
int consoleWrite(const char *fmt, ...)
{
va_list list;
va_start(list, fmt);
int writed = vprintf(fmt, list);
fflush(stdout);
va_end(list);
return writed;
}
//Akzeptieren Sie Zeichenfolgen von der Tastatur
size_t input(char *buf, size_t bufLen)
{
#define GabageBufSize 0x100
uint8_t bin[GabageBufSize];
char *savePtr = NULL;
char *token = NULL;
static_assert(sizeof(bin) == GabageBufSize, "Gabage buffer size not 255");
fgets(buf, bufLen, stdin);
token = strchr(buf, '\n');
if (token != NULL)
{
*token = '\0';
}
else
{
buf[bufLen - 1] = '\0';
while (token == NULL)
{
fgets(bin, GabageBufSize, stdin);
token = strchr(bin, '\n');
if (token != NULL)
{
break;
}
}
}
return strlen(buf);
}
//Dies ist eine schlechte Implementierung
void suspend(pthread_mutex_t* lock)
{
pthread_mutex_trylock(lock);
//Wenn es noch nie gesperrt wurde, wird es hier gesperrt
pthread_mutex_lock(lock);
pthread_mutex_unlock(lock);
}
void *messageSender(void *lock)
{
int count = 1;
while (true)
{
consoleWrite(".");
sleep(1);
if ((count % 3) == 0)
{
//Warten Sie hier, bis das Ereignis eintritt.
suspend((pthread_mutex_t*)lock);
}
count++;
}
}
int main(int argc, char *argv[])
{
pthread_t tid;
pthread_mutex_t lock;
char buf[32];
pthread_mutex_init(&lock, NULL);
pthread_create(&tid, NULL, messageSender, &lock);
while (true)
{
input(buf, 32);
pthread_mutex_unlock(&lock); //Der Entsperrvorgang wird von anderen Threads nicht garantiert.
consoleWrite("unlocked.\n");
}
pthread_join(tid, NULL);
}
~~ Wenn Daten in die Warteschlange kommen, verwenden Sie den Rückruf und drücken Sie pthread_mutex_unlock ~~ Durch das Entsperren des ~~ Mutex-Objekts wird der Thread neu gestartet. ~~ ~~ In der obigen Demo wird der Teil, in dem die Daten in der Warteschlange gespeichert sind, durch die Eingabe über die Tastatur ersetzt. ~~
~~ Ich habe es implementiert, solange ich es konnte, ohne über Leistung nachzudenken, also ~~ ~~ Wenn Sie weitere gute Ideen haben, tun Sie dies bitte. ~~ Ich werde zu einem späteren Zeitpunkt ein Beispiel mit pthread_cond_wait in einem anderen Beitrag schreiben.
Referenz: Abschnitt: Manpage C Bibliotheksfunktionen (3) PTHREAD_COND
//Nur Korrekturunterschied
typedef struct Suspend
{
pthread_mutex_t lockMutex;
pthread_cond_t lockCond;
} Suspend;
void suspend(Suspend *lock)
{
//Falsche Verwendung
pthread_mutex_trylock(&lock->lockMutex);
pthread_cond_wait(&lock->lockCond,&lock->lockMutex);
pthread_mutex_unlock(&lock->lockMutex);
}
void SuspendInit(Suspend *lock)
{
pthread_cond_init(&lock->lockCond, NULL);
pthread_mutex_init(&lock->lockMutex, NULL);
}
int main(int argc, char *argv[])
{
pthread_t tid;
Suspend lock;
char buf[32];
SuspendInit(&lock);
pthread_create(&tid, NULL, messageSender, &lock);
while (true)
{
input(buf, 32);
pthread_cond_signal(&lock.lockCond);
consoleWrite("unlocked.\n");
}
pthread_join(tid, NULL);
}
~~ Zunächst einmal habe ich das Gefühl, die Punkte, auf die hingewiesen wurde, behoben zu haben. ~~
typedef struct EventInfo
{
int state;
int read;
int write;
pthread_mutex_t mutex;
} EventInfo;
#define EventInfo_WAIT_BUSY 0
#define EventInfo_WAIT_READY 1
//Warten Sie, bis das Ereignis eintritt
void EventInfoWait(EventInfo *lock)
{
uint8_t msg;
pthread_mutex_lock(&lock->mutex);
lock->state = EventInfo_WAIT_READY;
pthread_mutex_unlock(&lock->mutex);
int r = read(lock->read, &msg, sizeof(uint8_t));
}
//nichts tun
void EventInfoRaisingEvent_None(EventInfo *lock)
{
}
//Nur benachrichtigen.
void EventInfoRaisingEvent_Send(EventInfo *lock)
{
static uint8_t msg = 0xdeadbeef;
write(lock->write, &msg, sizeof(uint8_t));
}
//Ereignis auslösen
void EventInfoRaisingEvent(EventInfo *lock)
{
static void (*EventInfoWakeupSendMessage[2])(EventInfo * lock) =
{
EventInfoWakeupSendMessage_None,
EventInfoWakeupSendMessage_Send};
pthread_mutex_lock(&lock->mutex);
EventInfoWakeupSendMessage[lock->state](lock);
lock->state = EventInfo_WAIT_BUSY;
pthread_mutex_unlock(&lock->mutex);
}
void *messageSender(void *lock)
{
int count = 1;
while (true)
{
consoleWrite(".");
sleep(1);
if ((count % 3) == 0)
{
//Warten Sie hier, bis das Ereignis eintritt.
EventInfoWait((EventInfo *)lock);
}
count++;
}
}
int EventInfoInit(EventInfo *lock)
{
int pfd[2];
int r = pipe(pfd);
if (r != 0)
{
return -1;
}
lock->state = EventInfo_WAIT_BUSY;
fcntl(pfd[1], F_SETFL, O_NONBLOCK);
lock->read = pfd[0];
lock->write = pfd[1];
pthread_mutex_init(&lock->mutex, NULL);
return 0;
}
int main(int argc, char *argv[])
{
pthread_t tid;
EventInfo lock;
char buf[32];
EventInfoInit(&lock);
pthread_create(&tid, NULL, messageSender, &lock);
while (true)
{
input(buf, 32);
EventInfoRaisingEvent(&lock);
consoleWrite("unlocked.\n");
}
pthread_join(tid, NULL);
return 0;
}
Fix, vielleicht sollte dies in Ordnung sein, da es den ursprünglichen Zweck erreichen wird.
Recommended Posts