使用C语言的线程无限打印1 2 3

使用C语言的线程无限打印1 2 3

线程是操作系统中非常重要的一部分,它是操作系统中执行的最小单位,是CPU调度和分配的基本单位。线程能够提高程序的运行效率,增加程序的并行性,常见的使用场景有多线程下载、多线程处理大量数据等。

本文将介绍如何使用C语言创建线程,并使用无限循环打印1 2 3的例子来说明线程的基本使用。

1. 线程的创建

在C语言中,线程的创建需要使用系统提供的线程库,如POSIX线程库。下面是一个创建线程的例子:

#include <stdio.h>

#include <pthread.h>

void *thread_func(void *arg)

{

// 线程的执行体

}

int main()

{

pthread_t tid;

pthread_create(&tid, NULL, thread_func, NULL);

return 0;

}

线程的创建是通过调用pthread_create函数来完成的,它的第一个参数是一个表示线程的变量pthread_t,第二个参数是线程属性,一般可以设置为NULL表示使用默认值;第三个参数是线程的执行体,它是一个指向函数的指针,该函数的返回值和参数要求是void*类型;第四个参数是传给执行体函数的参数,一般也可以设置为NULL表示不传任何参数。

线程创建成功后,会返回一个表示线程的ID,该ID可以用于等待线程的终止,或通过pthread_join函数获取线程的返回值。

2. 无限打印1 2 3的线程例子

下面是一个无限打印1 2 3的线程例子:

#include <stdio.h>

#include <pthread.h>

#include <stdlib.h>

void *print_num(void *arg)

{

int num = *(int*)arg;

while (1) {

printf("%d ", num);

fflush(stdout); // 刷新输出缓冲区

usleep(600000); // 休眠600毫秒

}

pthread_exit(NULL);

}

int main()

{

pthread_t tid1, tid2, tid3;

int num1 = 1, num2 = 2, num3 = 3;

pthread_create(&tid1, NULL, print_num, &num1);

pthread_create(&tid2, NULL, print_num, &num2);

pthread_create(&tid3, NULL, print_num, &num3);

pthread_join(tid1, NULL);

pthread_join(tid2, NULL);

pthread_join(tid3, NULL);

return 0;

}

上面的例子中定义了一个打印数字的函数print_num,该函数的参数是一个指向数字的指针,表示要打印的数字。在该函数中,通过一个死循环不停地打印数字,并使用usleep函数使线程休眠600毫秒,以免打印速度过快。

在主函数中,创建了三个线程,分别打印数字1、2和3,然后通过pthread_join函数等待三个线程的退出,使主线程挂起等待。

3. 使用信号量控制线程打印顺序

上面的例子中,三个线程是同时创建的,并且不保证打印顺序。如果要按照1 2 3的顺序打印数字,可以使用信号量来控制线程的执行顺序。

信号量是操作系统中一种同步机制,它用来协调多个线程的执行,可以控制线程的进入与退出,避免并发操作。

在C语言中,可以使用Semaphore库实现信号量,下面是一个按照1 2 3的顺序打印数字的例子:

#include <stdio.h>

#include <pthread.h>

#include <semaphore.h>

sem_t sem1, sem2, sem3;

void *print_num1(void *arg)

{

while (1) {

sem_wait(&sem1);

printf("1 ");

fflush(stdout);

sem_post(&sem2);

}

pthread_exit(NULL);

}

void *print_num2(void *arg)

{

while (1) {

sem_wait(&sem2);

printf("2 ");

fflush(stdout);

sem_post(&sem3);

}

pthread_exit(NULL);

}

void *print_num3(void *arg)

{

while (1) {

sem_wait(&sem3);

printf("3 ");

fflush(stdout);

sem_post(&sem1);

}

pthread_exit(NULL);

}

int main()

{

pthread_t tid1, tid2, tid3;

sem_init(&sem1, 0, 1); // 初始化信号量sem1,初值为1

sem_init(&sem2, 0, 0); // 初始化信号量sem2,初值为0

sem_init(&sem3, 0, 0); // 初始化信号量sem3,初值为0

pthread_create(&tid1, NULL, print_num1, NULL);

pthread_create(&tid2, NULL, print_num2, NULL);

pthread_create(&tid3, NULL, print_num3, NULL);

pthread_join(tid1, NULL);

pthread_join(tid2, NULL);

pthread_join(tid3, NULL);

sem_destroy(&sem1); // 销毁信号量

sem_destroy(&sem2);

sem_destroy(&sem3);

return 0;

}

上面的例子中,定义了三个线程分别打印数字1、2和3。在每个线程的执行体中,使用sem_wait函数等待对应的信号量,如果信号量值为0,则该线程被挂起等待;否则,该线程可以继续向下执行,并打印对应的数字,然后使用sem_post函数将下一个信号量的值加1,以便唤醒对应的线程。

在主函数中,首先通过sem_init函数对三个信号量进行初始化,然后创建三个线程并等待它们的退出,最后使用sem_destroy函数销毁三个信号量。

总结

本文介绍了如何使用C语言实现线程的创建,并使用一个无限打印1 2 3的例子来说明线程的基本使用。同时,还介绍了如何使用信号量来控制线程的执行顺序,以实现按照1 2 3的顺序打印数字。

线程是一项非常强大的技术,它可以提高程序的执行效率和并发处理能力,但也存在着一些问题,如线程安全、死锁、竞争等。因此,在使用线程时,一定要注意线程安全问题,合理地设计线程的执行逻辑,并尽量避免线程间的竞争和死锁。

后端开发标签