创建线程 ---- 实例
1、C语言 创建线程 执行2个不同的函数:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
// 第一个线程要执行的函数
void* function1(void* arg) {
printf("Function 1 is running\n");
// 执行一些任务...
return NULL;
}
// 第二个线程要执行的函数
void* function2(void* arg) {
printf("Function 2 is running\n");
// 执行一些任务...
return NULL;
}
int main() {
pthread_t thread1, thread2;
// 创建第一个线程执行function1
if (pthread_create(&thread1, NULL, function1, NULL) != 0) {
perror("Failed to create thread 1");
return EXIT_FAILURE;
}
// 创建第二个线程执行function2
if (pthread_create(&thread2, NULL, function2, NULL) != 0) {
perror("Failed to create thread 2");
return EXIT_FAILURE;
}
// 等待第一个线程结束
if (pthread_join(thread1, NULL) != 0) {
perror("Failed to join thread 1");
return EXIT_FAILURE;
}
// 等待第二个线程结束
if (pthread_join(thread2, NULL) != 0) {
perror("Failed to join thread 2");
return EXIT_FAILURE;
}
printf("Both threads have finished\n");
return EXIT_SUCCESS;
}
2、C 创建两个线程 通过传递数组 执行同一个函数 打印数组的内容:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
// 线程要执行的函数,接受一个void*类型的参数,这里参数是一个指向整型数组的指针
void* print_array(void* arg) {
int* array = (int*)arg;
int size = 5;
printf("Array contents: ");
for (int i = 0; i < size; ++i) {
printf("%d ", array[i]);
}
printf("\n");
return NULL;
}
int main() {
pthread_t thread1, thread2;
int array1[] = {1, 2, 3, 4, 5};
int array2[] = {6, 7, 8, 9, 10};
// 创建第一个线程,传递array1作为参数
if (pthread_create(&thread1, NULL, print_array, (void*)array1) != 0) {
perror("Failed to create thread 1");
return EXIT_FAILURE;
}
// 创建第二个线程,传递array2作为参数
if (pthread_create(&thread2, NULL, print_array, (void*)array2) != 0) {
perror("Failed to create thread 2");
return EXIT_FAILURE;
}
// 等待第一个线程结束
if (pthread_join(thread1, NULL) != 0) {
perror("Failed to join thread 1");
return EXIT_FAILURE;
}
// 等待第二个线程结束
if (pthread_join(thread2, NULL) != 0) {
perror("Failed to join thread 2");
return EXIT_FAILURE;
}
printf("Both threads have finished\n");
return EXIT_SUCCESS;
}
3、C 创建两个线程 访问一个全局变量:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
// 全局变量
int global_variable = 0;
// 互斥锁
pthread_mutex_t lock;
// 线程要执行的函数
void* increment(void* arg) {
// 锁定互斥锁
pthread_mutex_lock(&lock);
// 访问和修改全局变量:实际上是对锁进行操作,把内容放在 锁->内容ops->解锁 中
// 这里可以加上 内核那本书里面的设计与实现 什么时候需要加锁!
global_variable++;
printf("Global variable incremented to: %d\n", global_variable);
// 解锁互斥锁
pthread_mutex_unlock(&lock);
return NULL;
}
int main() {
pthread_t thread1, thread2;
// 初始化互斥锁
if (pthread_mutex_init(&lock, NULL) != 0) {
perror("Failed to initialize mutex");
return EXIT_FAILURE;
}
// 创建两个线程
if (pthread_create(&thread1, NULL, increment, NULL) != 0) {
perror("Failed to create thread 1");
return EXIT_FAILURE;
}
if (pthread_create(&thread2, NULL, increment, NULL) != 0) {
perror("Failed to create thread 2");
return EXIT_FAILURE;
}
// 等待两个线程结束
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
// 销毁互斥锁
pthread_mutex_destroy(&lock);
printf("Final value of global variable: %d\n", global_variable);
return EXIT_SUCCESS;
}
读取-修改竞态条件(Read-Modify-Write Race Condition):当一个线程正在读取变量的值时,另一个线程可能会修改这个变量。如果第一个线程在读取过程中第二个线程改变了变量的值,第一个线程可能会得到一个不一致的值。
内存可见性问题:在某些编译器和处理器优化下,没有锁的保护可能导致一个线程看不到另一个线程对共享变量所做的修改,因为编译器和处理器可能会对内存访问进行重排序。
数据依赖性问题:如果shared_data的值依赖于程序中的其他状态,并且这些状态可能被其他线程修改,那么即使只是读取shared_data,也需要确保在读取时这些依赖状态不会被改变。
为了保证线程安全和数据的一致性,即使是读取操作,也应该在修改和读取共享变量时使用互斥锁。这样可以确保在任何时候只有一个线程能够访问共享变量,无论是读取还是写入。
在实际应用中,如果性能是一个关键考虑因素,并且读操作远远多于写操作,可以考虑使用其他同步机制,如 读写锁(read-write lock),它允许多个线程同时读取,但在写入时仍然保证互斥。 然而,这仍然需要仔细设计以避免潜在的死锁和性能问题。对于简单的用例或者写操作较为频繁的情况,使用互斥锁通常是最直接和安全的方法。
4、C 创建两个线程 读写一个全局变量:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
// 全局变量
int shared_data = 0;
// 互斥锁
pthread_mutex_t mutex;
// 读取全局变量的线程函数
void* reader(void* arg) {
int data;
pthread_mutex_lock(&mutex);
data = shared_data;
pthread_mutex_unlock(&mutex);
printf("Reader thread read data: %d\n", data);
return NULL;
}
// 修改全局变量的线程函数
void* writer(void* arg) {
pthread_mutex_lock(&mutex);
shared_data = *(int*)arg;
pthread_mutex_unlock(&mutex);
printf("Writer thread wrote data: %d\n", shared_data);
return NULL;
}
int main() {
pthread_t reader_thread, writer_thread;
int new_data = 42;
// 初始化互斥锁
if (pthread_mutex_init(&mutex, NULL) != 0) {
perror("Failed to initialize mutex");
return EXIT_FAILURE;
}
// 创建读取线程
if (pthread_create(&reader_thread, NULL, reader, NULL) != 0) {
perror("Failed to create reader thread");
return EXIT_FAILURE;
}
// 创建写入线程
if (pthread_create(&writer_thread, NULL, writer, (void*)&new_data) != 0) {
perror("Failed to create writer thread");
return EXIT_FAILURE;
}
// 等待线程结束
pthread_join(reader_thread, NULL);
pthread_join(writer_thread, NULL);
// 销毁互斥锁
pthread_mutex_destroy(&mutex);
return EXIT_SUCCESS;
}