gxc老师独有的“抓贼实验”
这个代码能手动抓到贼,当然最好可以再加一个程序来自动捕捉贼~
题目描述
通过c语言的多线程,开启多个消费者一个生产者,得到生产消费的输出,在输出中查找竞争条件(race condition),捕获错误现场。
实验涉及的知识点
1、线程创建pthread_create
线程创建函数包含四个变量,分别为:
1.一个线程变量名,被创建线程的标识
2.线程的属性指针,缺省为NULL即可
3.被创建线程的程序代码
4.程序代码的参数
pthread_create(&thrd1, NULL, (void *)&thread_function, (void *) &some_argument);
2、结束线程 pthread_exit
线程结束调用实例:pthread_exit(void *retval); //retval用于存放线程结束的退出状态
3、线程等待 pthread_join
pthread_create调用成功以后,新线程和老线程谁先执行,谁后执行用户是不知道的,这一块取决与操作系统对线程的调度,如果我们需要等待指定线程结束,需要使用pthread_join函数,这个函数实际上类似与多进程编程中的waitpid。 举个例子,以下假设 A 线程调用 pthread_join 试图去操作B线程,该函数将A线程阻塞,直到B线程退出,当B线程退出以后,A线程会收集B线程的返回码。 该函数包含两个参数:
pthread_t th //th是要等待结束的线程的标识
void **thread_return //指针thread_return指向的位置存放的是终止线程的返回状态。
调用实例:pthread_join(thrd1, NULL);
源代码
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define BUFFER_SIZE 10
typedef struct
{
int a;
} item;
item buffer[BUFFER_SIZE];
int in = 0;
int out = 0;
item nextConsumed;
item nextProduced;
int *consumer(void *arg)
{
nextConsumed.a = 0;
while (1)
{
while (in == out)
; /*do nothingf*/
nextConsumed.a++;
nextConsumed = buffer[out];
out = (out + 1) % BUFFER_SIZE;
/*consume the item in nextConsumed*/
printf("consume the item in nextConsumed\n");
printf("consume %d\n", nextConsumed.a);
}
return NULL;
}
int *producer(void *arg)
{
nextProduced.a = 0;
while (1)
{
/*produce an item in nextProduced*/
while (((in + 1) % BUFFER_SIZE) == out)
;
/*do nothing*/
nextProduced.a++;
buffer[in] = nextProduced;
in = (in + 1) % BUFFER_SIZE;
printf("produce an item in nextProduced\n");
printf("produce %d\n", nextProduced.a);
}
return NULL;
}
int main(void)
{
pthread_t con_thid1;
pthread_t con_thid2;
pthread_t con_thid3;
pthread_t pro_thid;
if (pthread_create(&con_thid1, NULL, (void *)consumer, NULL) != 0)
{
printf("consumer creation failed\n");
}
if (pthread_create(&con_thid2, NULL, (void *)consumer, NULL) != 0)
{
printf("consumer creation failed\n");
}
if (pthread_create(&con_thid3, NULL, (void *)consumer, NULL) != 0)
{
printf("consumer creation failed\n");
}
if (pthread_create(&pro_thid, NULL, (void *)producer, NULL) != 0)
{
printf("producer creation failed\n");
}
pthread_join(con_thid1, NULL);
pthread_join(con_thid2, NULL);
pthread_join(con_thid3, NULL);
pthread_join(pro_thid, NULL);
printf("ok\n");
}