Suche…
Einfacher Thread ohne Argumente
Dieses grundlegende Beispiel zählt mit unterschiedlichen Raten für zwei Threads, die als sync (main) und async (neuer Thread) bezeichnet werden. Der Hauptthread zählt bei 1 Hz (1s) bis 15, während der zweite bei 0,5 Hz (2s) bis 10 zählt. Da der Haupt-Thread früher beendet wird, verwenden wir pthread_join
, um das Ende pthread_join
zu warten.
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
/* This is the function that will run in the new thread. */
void * async_counter(void * pv_unused) {
int j = 0;
while (j < 10) {
printf("async_counter: %d\n", j);
sleep(2);
j++;
}
return NULL;
}
int main(void) {
pthread_t async_counter_t;
int i;
/* Create the new thread with the default flags and without passing
* any data to the function. */
if (0 != (errno = pthread_create(&async_counter_t, NULL, async_counter, NULL))) {
perror("pthread_create() failed");
return EXIT_FAILURE;
}
i = 0;
while (i < 15) {
printf("sync_counter: %d\n", i);
sleep(1);
i++;
}
printf("Waiting for async counter to finish ...\n");
if (0 != (errno = pthread_join(async_counter_t, NULL))) {
perror("pthread_join() failed");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
Von hier kopiert: http://stackoverflow.com/documentation/c/3873/posix-threads/13405/simple-thread-ohne die Argumente, bei denen sie ursprünglich von M. Rubio-Roy erstellt wurde
Einfache Mutex-Verwendung
Die POSIX-Thread-Bibliothek bietet die Implementierung des Mutex-Grundelements, das für den gegenseitigen Ausschluss verwendet wird. Mutex wird mit erstellt pthread_mutex_init
und unter Verwendung zerstört pthread_mutex_destroy
. Erhalten eines Mutex kann getan werden unter Verwendung von pthread_mutex_lock
oder pthread_mutex_trylock
, (je nachdem , ob das Timeout gewünscht ist ) und Freigeben eines Mutex über erfolgt pthread_mutex_unlock
.
Es folgt ein einfaches Beispiel, in dem ein Mutex verwendet wird, um den Zugriff auf kritische Abschnitte zu serialisieren. Zunächst das Beispiel ohne Verwendung eines Mutex. Beachten Sie, dass dieses Programm hat Daten Rennen wegen nicht synchronisierten Zugriff auf global_resource
durch die beiden Fäden. Daher hat dieses Programm undefiniertes Verhalten :
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
// Global resource accessible to all threads
int global_resource;
// Threading routine which increments the resource 10 times and prints
// it after every increment
void* thread_inc (void* arg)
{
for (int i = 0; i < 10; i++)
{
global_resource++;
printf("Increment: %d\n", global_resource);
// Make this thread slower, so the other one
// can do more work
sleep(1);
}
printf("Thread inc finished.\n");
return NULL;
}
// Threading routine which decrements the resource 10 times and prints
// it after every decrement
void* thread_dec (void* arg)
{
for (int i = 0; i < 10; i++)
{
global_resource--;
printf("Decrement: %d\n", global_resource);
}
printf("Thread dec finished.\n");
return NULL;
}
int main (int argc, char** argv)
{
pthread_t threads[2];
if (0 != (errno = pthread_create(&threads[0], NULL, thread_inc, NULL)))
{
perror("pthread_create() failed");
return EXIT_FAILURE;
}
if (0 != (errno = pthread_create(&threads[1], NULL, thread_dec, NULL)))
{
perror("pthread_create() failed");
return EXIT_FAILURE;
}
// Wait for threads to finish
for (int i = 0; i < 2; i++)
{
if (0 != (errno = pthread_join(threads[i], NULL))) {
perror("pthread_join() failed");
return EXIT_FAILURE;
}
}
return EXIT_SUCCESS;
}
Eine mögliche Ausgabe ist:
Increment: 1
Decrement: 0
Decrement: -1
Decrement: -2
Decrement: -3
Decrement: -4
Decrement: -5
Decrement: -6
Decrement: -7
Decrement: -8
Decrement: -9
Thread dec finished.
Increment: -8
Increment: -7
Increment: -6
Increment: -5
Increment: -4
Increment: -3
Increment: -2
Increment: -1
Increment: 0
Thread inc finished.
Wenn wir diese Threads synchronisieren möchten, um zuerst ganz nach oben oder unten zu inkrementieren oder zu dekrementieren und dann auf andere Weise zu tun, müssen wir ein Synchronisationsprimitiv wie Mutex verwenden:
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
// Global resource accessible to all threads
int global_resource;
// Mutex protecting the resource
pthread_mutex_t mutex;
// Threading routine which increments the resource 10 times and prints
// it after every increment
void* thread_inc (void* arg)
{
// Pointer to mutex is passed as an argument
pthread_mutex_t* mutex = arg;
// Execute the following code without interrupts, all the way to the
// point B
if (0 != (errno = pthread_mutex_lock(mutex)))
{
perror("pthread_mutex_lock failed");
exit(EXIT_FAILURE);
}
for (int i = 0; i < 10; i++)
{
global_resource++;
printf("Increment: %d\n", global_resource);
// Make this thread slower, so the other one
// can do more work
sleep(1);
}
printf("Thread inc finished.\n");
// Point B:
if (0 != (errno = pthread_mutex_unlock(mutex)))
{
perror("pthread_mutex_unlock failed");
exit(EXIT_FAILURE);
}
return NULL;
}
// Threading routine which decrements the resource 10 times and prints
// it after every decrement
void* thread_dec (void* arg)
{
// Pointer to mutex is passed as an argument
pthread_mutex_t* mutex = arg;
if (0 != (errno = pthread_mutex_lock(mutex)))
{
perror("pthread_mutex_lock failed");
exit(EXIT_FAILURE);
}
for (int i = 0; i < 10; i++)
{
global_resource--;
printf("Decrement: %d\n", global_resource);
}
printf("Thread dec finished.\n");
// Point B:
if (0 != (errno = pthread_mutex_unlock(mutex)))
{
perror("pthread_mutex_unlock failed");
exit(EXIT_FAILURE);
}
return NULL;
}
int main (int argc, char** argv)
{
pthread_t threads[2];
pthread_mutex_t mutex;
// Create a mutex with the default parameters
if (0 != (errno = pthread_mutex_init(&mutex, NULL)))
{
perror("pthread_mutex_init() failed");
return EXIT_FAILURE;
}
if (0 != (errno = pthread_create(&threads[0], NULL, thread_inc, &mutex)))
{
perror("pthread_create() failed");
return EXIT_FAILURE;
}
if (0 != (errno = pthread_create(&threads[1], NULL, thread_dec, &mutex)))
{
perror("pthread_create() failed");
return EXIT_FAILURE;
}
// Wait for threads to finish
for (int i = 0; i < 2; i++)
{
if (0 != (errno = pthread_join(threads[i], NULL))) {
perror("pthread_join() failed");
return EXIT_FAILURE;
}
}
// Both threads are guaranteed to be finished here, so we can safely
// destroy the mutex
if (0 != (errno = pthread_mutex_destroy(&mutex)))
{
perror("pthread_mutex_destroy() failed");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
Eine der möglichen Ausgaben ist
Increment: 1
Increment: 2
Increment: 3
Increment: 4
Increment: 5
Increment: 6
Increment: 7
Increment: 8
Increment: 9
Increment: 10
Thread inc finished.
Decrement: 9
Decrement: 8
Decrement: 7
Decrement: 6
Decrement: 5
Decrement: 4
Decrement: 3
Decrement: 2
Decrement: 1
Decrement: 0
Thread dec finished.
Die andere mögliche Ausgabe wäre invers, falls thread_dec
den Mutex erhält.