用C语言创建3个线程,分别输出“1”、“2”、“3”,并放入循环中
时间: 2023-11-21 13:04:11 浏览: 36
以下是使用C语言创建3个线程,分别输出“1”、“2”、“3”,并放入循环中的示例代码:
```c
#include <stdio.h>
#include <pthread.h>
void* print_number(void* arg) {
int number = *(int*)arg;
printf("%d\n", number);
pthread_exit(NULL);
}
int main() {
pthread_t threads[3];
int numbers[] = {1, 2, 3};
for (int i = 0; i < 3; i++) {
pthread_create(&threads[i], NULL, print_number, &numbers[i]);
}
for (int i = 0; i < 3; i++) {
pthread_join(threads[i], NULL);
}
return 0;
}
```
在上面的代码中,我们使用了pthread库来创建线程。首先定义了一个print_number函数,用于在线程中输出传入的数字。然后在主函数中创建了3个线程,并分别传入1、2、3这3个数字。接下来使用for循环等待所有线程执行完毕,最后退出程序。
相关问题
生产者消费者问题c语言,2个生产者,3个消费者,给出代码和分析
生产者消费者问题是一个经典的并发编程问题,主要是解决多线程环境下生产者和消费者之间的同步问题。在C语言中,我们可以使用线程和信号量来解决这个问题。
以下是一个使用线程和信号量的C语言代码示例,其中有2个生产者和3个消费者。在代码中,我们使用了一个缓冲区来存储生产者生产的数据,并使用信号量来控制生产者和消费者之间的同步。
```c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define BUFFER_SIZE 10
int buffer[BUFFER_SIZE];
int count = 0;
int in = 0;
int out = 0;
sem_t empty;
sem_t full;
pthread_mutex_t mutex;
void *producer(void *arg)
{
int item;
while(1)
{
item = rand() % 100; //生产一个随机数
sem_wait(&empty); //等待空缓冲区
pthread_mutex_lock(&mutex); //加锁
buffer[in] = item;
in = (in + 1) % BUFFER_SIZE;
count++;
printf("Produced item: %d\n", item);
pthread_mutex_unlock(&mutex); //解锁
sem_post(&full); //发送一个满缓冲区信号
}
}
void *consumer(void *arg)
{
int item;
while(1)
{
sem_wait(&full); //等待满缓冲区
pthread_mutex_lock(&mutex); //加锁
item = buffer[out];
out = (out + 1) % BUFFER_SIZE;
count--;
printf("Consumed item: %d\n", item);
pthread_mutex_unlock(&mutex); //解锁
sem_post(&empty); //发送一个空缓冲区信号
}
}
int main()
{
pthread_t p1, p2, c1, c2, c3;
//初始化信号量和互斥量
sem_init(&empty, 0, BUFFER_SIZE);
sem_init(&full, 0, 0);
pthread_mutex_init(&mutex, NULL);
//创建线程
pthread_create(&p1, NULL, producer, NULL);
pthread_create(&p2, NULL, producer, NULL);
pthread_create(&c1, NULL, consumer, NULL);
pthread_create(&c2, NULL, consumer, NULL);
pthread_create(&c3, NULL, consumer, NULL);
//等待线程结束
pthread_join(p1, NULL);
pthread_join(p2, NULL);
pthread_join(c1, NULL);
pthread_join(c2, NULL);
pthread_join(c3, NULL);
//销毁信号量和互斥量
sem_destroy(&empty);
sem_destroy(&full);
pthread_mutex_destroy(&mutex);
return 0;
}
```
在上面的代码中,我们使用了两个信号量和一个互斥量来控制生产者和消费者之间的同步。empty信号量表示空缓冲区数量,当empty为0时,生产者需要等待。full信号量表示满缓冲区数量,当full为0时,消费者需要等待。mutex互斥量用于保护buffer、count、in和out这些共享变量。
当一个生产者生产一个数据时,它会将该数据放入缓冲区,并将in指针向后移动一个位置,同时增加count计数器。当一个消费者消费一个数据时,它会从缓冲区中取出一个数据,并将out指针向后移动一个位置,同时减少count计数器。
在代码中,我们使用了无限循环来模拟生产者和消费者的操作,直到程序被强制终止。在主函数中,我们创建了5个线程,包括2个生产者和3个消费者,并等待所有线程结束后销毁信号量和互斥量。
用c语言实现一个动态线程池
下面是一个用 C 语言实现的简单动态线程池的示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
typedef struct {
void (*task_func)(void*); // 任务函数指针
void* task_arg; // 任务参数
} Task;
typedef struct {
Task* tasks; // 任务数组
int capacity; // 任务数组容量
int size; // 当前任务数量
int front; // 队列头索引
int rear; // 队列尾索引
pthread_mutex_t lock; // 互斥锁
pthread_cond_t not_empty; // 非空条件变量
pthread_cond_t not_full; // 非满条件变量
} ThreadPool;
void task_queue_init(ThreadPool* pool, int capacity) {
pool->tasks = (Task*)malloc(sizeof(Task) * capacity);
pool->capacity = capacity;
pool->size = 0;
pool->front = 0;
pool->rear = 0;
pthread_mutex_init(&pool->lock, NULL);
pthread_cond_init(&pool->not_empty, NULL);
pthread_cond_init(&pool->not_full, NULL);
}
void task_queue_destroy(ThreadPool* pool) {
free(pool->tasks);
pthread_mutex_destroy(&pool->lock);
pthread_cond_destroy(&pool->not_empty);
pthread_cond_destroy(&pool->not_full);
}
void task_queue_push(ThreadPool* pool, Task task) {
pthread_mutex_lock(&pool->lock);
while (pool->size == pool->capacity) {
pthread_cond_wait(&pool->not_full, &pool->lock);
}
pool->tasks[pool->rear] = task;
pool->rear = (pool->rear + 1) % pool->capacity;
pool->size++;
pthread_cond_signal(&pool->not_empty);
pthread_mutex_unlock(&pool->lock);
}
Task task_queue_pop(ThreadPool* pool) {
pthread_mutex_lock(&pool->lock);
while (pool->size == 0) {
pthread_cond_wait(&pool->not_empty, &pool->lock);
}
Task task = pool->tasks[pool->front];
pool->front = (pool->front + 1) % pool->capacity;
pool->size--;
pthread_cond_signal(&pool->not_full);
pthread_mutex_unlock(&pool->lock);
return task;
}
void* worker_thread(void* arg) {
ThreadPool* pool = (ThreadPool*)arg;
while (1) {
Task task = task_queue_pop(pool);
task.task_func(task.task_arg);
}
return NULL;
}
void thread_pool_init(ThreadPool* pool, int capacity, int num_workers) {
task_queue_init(pool, capacity);
pthread_t* threads = (pthread_t*)malloc(sizeof(pthread_t) * num_workers);
for (int i = 0; i < num_workers; i++) {
pthread_create(&threads[i], NULL, worker_thread, pool);
}
}
void thread_pool_destroy(ThreadPool* pool, int num_workers) {
for (int i = 0; i < num_workers; i++) {
task_queue_push(pool, (Task){NULL, NULL}); // 发送结束任务给所有工作线程
}
pthread_t* threads = (pthread_t*)malloc(sizeof(pthread_t) * num_workers);
for (int i = 0; i < num_workers; i++) {
pthread_join(threads[i], NULL);
}
task_queue_destroy(pool);
}
// 示例任务函数
void my_task(void* arg) {
printf("Hello from task\n");
}
int main() {
ThreadPool pool;
thread_pool_init(&pool, 10, 5);
for (int i = 0; i < 10; i++) {
task_queue_push(&pool, (Task){my_task, NULL});
}
thread_pool_destroy(&pool, 5);
return 0;
}
```
上述示例使用了一个循环队列来实现任务队列,通过互斥锁和条件变量来保证线程安全。`ThreadPool` 结构体表示线程池,包含了任务队列和相关的属性。`task_queue_push` 和 `task_queue_pop` 分别用于将任务放入队列和从队列中取出任务。
`worker_thread` 函数是工作线程的入口函数,它会不断从任务队列中取出任务并执行。在 `thread_pool_init` 函数中创建了指定数量的工作线程,并开始执行任务。
注意,这只是一个简单的示例实现,实际使用时可能需要更多的错误处理和线程安全的考虑。另外,该示例没有实现线程池的动态调整功能,可以根据实际需求进行扩展。
相关推荐
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![application/x-rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)