mirror of
https://github.com/ION606/learn.git
synced 2026-05-14 21:06:56 +00:00
initial commit
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,147 @@
|
||||
/* mutex-example.c */
|
||||
|
||||
/* multi-threaded example showing multiple threads adding to
|
||||
* a shared set of global variables
|
||||
*
|
||||
* specifically, thread A sums 1 + 2 + ... + a, whereas
|
||||
* thread B sums 1 + 2 + ... + b
|
||||
*
|
||||
* both threads A and B add to global_sum, which should
|
||||
* then be 1 + 2 + ... + a + 1 + 2 + ... + b
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
|
||||
/* shared global variables */
|
||||
int global_a; /* sum: 1 + 2 + ... + a */
|
||||
int global_b; /* sum: 1 + 2 + ... + b */
|
||||
int global_sum; /* global_a + global_b */
|
||||
|
||||
/* function prototypes for the thread functions */
|
||||
void * whattodo_for_a( void * arg );
|
||||
void * whattodo_for_b( void * arg );
|
||||
void * noise( void * arg );
|
||||
|
||||
/* global mutex variables */
|
||||
pthread_mutex_t mutex_on_global_sum = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
int main( int argc, char * argv[] )
|
||||
{
|
||||
if ( argc != 3 )
|
||||
{
|
||||
fprintf( stderr, "ERROR: Invalid input(s)\n" );
|
||||
fprintf( stderr, "USAGE: a.out <a> <b>\n" );
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
int a = atoi( argv[1] );
|
||||
int b = atoi( argv[2] );
|
||||
|
||||
int expected_sum_a = 0;
|
||||
for ( int i = 1 ; i <= a ; i++ ) expected_sum_a += i;
|
||||
|
||||
int expected_sum_b = 0;
|
||||
for ( int i = 1 ; i <= b ; i++ ) expected_sum_b += i;
|
||||
|
||||
int expected_global_sum = expected_sum_a + expected_sum_b;
|
||||
|
||||
|
||||
global_sum = global_a = global_b = 0;
|
||||
|
||||
pthread_t tid1, tid2, tid3;
|
||||
int rc;
|
||||
|
||||
rc = pthread_create( &tid1, NULL, whattodo_for_a, &a );
|
||||
if ( rc != 0 ) { fprintf( stderr, "pthread_create() failed (%d)\n", rc ); return EXIT_FAILURE; }
|
||||
|
||||
rc = pthread_create( &tid2, NULL, whattodo_for_b, &b );
|
||||
if ( rc != 0 ) { fprintf( stderr, "pthread_create() failed (%d)\n", rc ); return EXIT_FAILURE; }
|
||||
|
||||
/* TO DO: add a third call to pthread_create() and have that
|
||||
* child thread call whattodo_for_b(), which then will
|
||||
* require synchronization on global_b...
|
||||
*/
|
||||
|
||||
rc = pthread_create( &tid3, NULL, noise, NULL );
|
||||
|
||||
|
||||
rc = pthread_join( tid1, NULL );
|
||||
if ( rc != 0 ) { fprintf( stderr, "pthread_join() failed (%d)\n", rc ); return EXIT_FAILURE; }
|
||||
|
||||
rc = pthread_join( tid2, NULL );
|
||||
if ( rc != 0 ) { fprintf( stderr, "pthread_join() failed (%d)\n", rc ); return EXIT_FAILURE; }
|
||||
|
||||
/* no overlap in individual writes/updates to global_a */
|
||||
printf( "MAIN: global a is %d (expected %d)%s\n", global_a, expected_sum_a,
|
||||
global_a != expected_sum_a ? " **************" : "" );
|
||||
|
||||
/* no overlap in individual writes/updates to global_b */
|
||||
printf( "MAIN: global b is %d (expected %d)%s\n", global_b, expected_sum_b,
|
||||
global_b != expected_sum_b ? " **************" : "" );
|
||||
|
||||
/* potential overlap in individual writes/updates to global_sum */
|
||||
printf( "MAIN: global sum is %d (expected %d)%s\n", global_sum, expected_global_sum,
|
||||
global_sum != expected_global_sum ? " **************" : "" );
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void * whattodo_for_a( void * arg )
|
||||
{
|
||||
int a = *(int *)arg;
|
||||
|
||||
for ( int i = 1 ; i <= a ; i++ )
|
||||
{
|
||||
printf( "Thread A: adding %d to global_a\n", i );
|
||||
global_a += i;
|
||||
|
||||
printf( "Thread A: adding %d to global_sum\n", i );
|
||||
|
||||
pthread_mutex_lock( &mutex_on_global_sum );
|
||||
{
|
||||
global_sum += i; /* CRITICAL SECTION */
|
||||
}
|
||||
pthread_mutex_unlock( &mutex_on_global_sum );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void * whattodo_for_b( void * arg )
|
||||
{
|
||||
int b = *(int *)arg;
|
||||
|
||||
for ( int i = 1 ; i <= b ; i++ )
|
||||
{
|
||||
printf( "Thread B: adding %d to global_b\n", i );
|
||||
global_b += i;
|
||||
|
||||
printf( "Thread B: adding %d to global_sum\n", i );
|
||||
|
||||
pthread_mutex_lock( &mutex_on_global_sum );
|
||||
{
|
||||
global_sum += i; /* CRITICAL SECTION */
|
||||
}
|
||||
pthread_mutex_unlock( &mutex_on_global_sum );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void * noise( void * arg )
|
||||
{
|
||||
for ( int i = 1 ; i <= 1000 ; i++ )
|
||||
{
|
||||
usleep( 100 );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
|
||||
int main() {
|
||||
int pipefd[2];
|
||||
int rc = pipe(pipefd);
|
||||
|
||||
if (rc == -1) {
|
||||
perror("pipe() failed!");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
pid_t pid = fork();
|
||||
|
||||
if (pid == 0) {
|
||||
perror("fork() failed!");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
// close the read end of the pipe (there's no need to use it in this process)
|
||||
close(pipefd[0]);
|
||||
|
||||
// Write the bytes to the pipe
|
||||
char* toWrite = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
int bytes_written = write(pipefd[1], toWrite, 26);
|
||||
printf("Child process wrote \"%s\" (%d bytes)\n", toWrite, bytes_written);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
else {
|
||||
// close the write end of the pipe (there's no need to use it in this process)
|
||||
close(pipefd[0]);
|
||||
|
||||
int stat;
|
||||
pid_t cpid = waitpid(pid, &stat, 0);
|
||||
|
||||
printf("child exited with status %d\n", WEXITSTATUS(stat));
|
||||
|
||||
char buffer[20];
|
||||
int bytes_read = read(pipefd[0], buffer, 10);
|
||||
|
||||
// assume the data is char data
|
||||
buffer[bytes_read] = '\0';
|
||||
|
||||
printf("Parent process read \"%s\" (%d bytes)\n", buffer, bytes_read);
|
||||
|
||||
// close the write buffer
|
||||
close(pipefd[1]);
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
Reference in New Issue
Block a user