作业1
司机: 接收售票员关门信号-->开车 //SIGUSR1
接收到站信号-->停车 //SIGINT
发送开门信号给售票员-->等待关门信号 //pause() 挂起进程
售票员:发送关门信号
接收开门信号-->开门 //SIGUSR2
#include <stdio.h>
#include <string.h>
#include <unistd.h> //fork ()
#include <stdlib.h>
#include <sys/types.h> //kill()
#include <signal.h> //signal()
pid_t pid = -1;
//司机:到站停车 --> SIGINT ctrl+c
// 关门开车 --> SIGUSR1
void handleDriver(int sig)
{
if (SIGINT == sig)
{
printf("到站了...\\n");
sleep(1);
printf("司机开始停车...\\n");
sleep(1);
int ret = 0;
ret = kill(pid, SIGUSR2); //发送信号给售票员让她开门
if (-1 == ret)
{
perror("kill");
}
}
else if (SIGUSR1 == sig)
{
printf("司机开始开车...\\n");
sleep(1);
printf("车正在跑...\\n");
sleep(1);
}
}
//售票员:开门 -->SIGUSR2
void handleConductor(int sig)
{
if (SIGUSR2 == sig)
{
printf("售票员开门...\\n");
sleep(1);
printf("乘客上车...\\n");
sleep(1);
printf("售票员关门...\\n");
sleep(1);
kill(getppid(), SIGUSR1); //售票员发送信号给司机开车
}
}
int main(void)
{
pid = fork();
if (pid > 0) //driver
{
signal(SIGINT, handleDriver);
signal(SIGUSR1, handleDriver);
printf("司机等待售票员做好开车准备...\\n");
while (1)
{
pause();
}
}
else if (0 == pid) //conductor
{
signal(SIGINT, SIG_IGN);
signal(SIGUSR2, handleConductor);
sleep(1);
//发送一个开车信号让其开车
kill(getppid(), SIGUSR1);
while (1)
{
pause();
}
}
else if (-1 == pid)
{
perror("fork");
return -1;
}
return 0;
}
运行结果:
创建线程
#include <pthread.h> //pthread_create()
#include <stdio.h>
#include <string.h> //strerror()
#include <errno.h> //errno
#include <unistd.h>
void *thread_run(void *arg)
{
while (1)
{
printf("this is thread_run...\\n");
sleep(1);
}
return NULL;
}
int main(void)
{
pthread_t thread;
int ret = 0;
ret = pthread_create(&thread, NULL, thread_run, NULL);
if (0 != ret)
{
printf("errno:%d, error:%s\\n", ret, strerror(ret));
return -1;
}
while (1)
{
printf("this is main...\\n");
sleep(1);
}
return 0;
}
运行结果:
pthread_arg.c
#include <pthread.h> //pthread_create()
#include <stdio.h>
#include <string.h> //strerror()
#include <errno.h> //errno
#include <unistd.h>
typedef struct Student
{
int iId;
char caName[32];
float fScore;
}Student;
void *thread_run(void *arg)
{
while (1)
{
//printf("this is thread_run...arg = %d\\n", *(int *)arg);
//printf("this is thread_run...arg = %d\\n", (int)arg);
Student *pStu = (Student *)arg;
printf("id:%d, name:%s, score:%.2f\\n"
, pStu->iId, pStu->caName, pStu->fScore);
sleep(1);
}
return NULL;
}
int main(void)
{
pthread_t thread;
int ret = 0;
int iArg = 1888;
//ret = pthread_create(&thread, NULL, thread_run, &iArg);
//ret = pthread_create(&thread, NULL, thread_run, (void *)iArg);
//ret = pthread_create(&thread, NULL, thread_run, (void *)1888);
Student stu = {1001, "zhangsan", 89};
ret = pthread_create(&thread, NULL, thread_run, &stu);
//ret = pthread_create(&thread, NULL, thread_run, (void *)stu); //error
if (0 != ret)
{
printf("errno:%d, error:%s\\n", ret, strerror(ret));
return -1;
}
while (1)
{
printf("this is main...\\n");
pause();
}
return 0;
}
运行结果:
pthread_cancel_exit.c
#include <pthread.h> //pthread_create()
#include <stdio.h>
#include <string.h> //strerror()
#include <errno.h> //errno
#include <unistd.h>
void *thread_run(void *arg)
{
//在线程函数中调用pthread_setcancelstate来设置
//不同意结束线程请求,阻塞线程结束请求
//直到线程允许接收线程结束请求
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
while (1)
{
printf("this is thread_run...\\n");
sleep(1);
//break;
//结束所属线程
//pthread_exit(NULL);
}
return NULL;
}
int main(void)
{
pthread_t thread;
int ret = 0;
ret = pthread_create(&thread, NULL, thread_run, NULL);
if (0 != ret)
{
printf("errno:%d, error:%s\\n", ret, strerror(ret));
return -1;
}
sleep(3);
//发送一个结束线程请求给指定的线程
//默认情况下,线程会同意该结束线程请求
//还可以设置不同意
//pthread_cancel(thread);
//若存在主线程中,如果含有其他线程存在,
//则阻塞等待线程的结束
//若没有其他线程,则结束程序
pthread_exit(NULL);
while (1)
{
printf("this is main...\\n");
sleep(1);
}
return 0;
}
运算结果:
pthread_exit.c
#include <pthread.h> //pthread_create()
#include <stdio.h>
#include <string.h> //strerror()
#include <errno.h> //errno
#include <unistd.h> //sleep()
#include <stdlib.h> //exit()
//一个进程创建线程后,创建的线程从属于该进程
//不独立于进程,共享进程的所有资源
//线程是最小的执行单元,
//若一个进程没有创建线程,我们既可以把它看做是进程,也可以是相当于线程
//若一个进程创建线程后,我们可以将该进程称之为主线程
//一个进程可以创建多个线程,线程之间资源共享
void *thread_run(void *arg)
{
int i = 0;
while (1)
{
printf("this is thread_run...\\n");
sleep(1);
i++;
if (5 == i)
{
//使用return 只能结束当前线程
//return NULL;
//会将该线程所属的进程挂掉,当然线程也会挂掉
exit(1);
}
}
return NULL;
}
int main(void)
{
pthread_t thread;
int ret = 0;
ret = pthread_create(&thread, NULL, thread_run, NULL);
if (0 != ret)
{
printf("errno:%d, error:%s\\n", ret, strerror(ret));
return -1;
}
while (1)
{
printf("this is main...\\n");
sleep(1);
}
return 0;
}
运算结果:
pthread_join.c
#include <pthread.h> //pthread_create()
#include <stdio.h>
#include <string.h> //strerror()
#include <errno.h> //errno
#include <unistd.h>
void *thread_run(void *arg)
{
while (1)
{
printf("this is thread_run...\\n");
sleep(1);
}
return NULL;
}
int main(void)
{
pthread_t thread;
int ret = 0;
ret = pthread_create(&thread, NULL, thread_run, NULL);
if (0 != ret)
{
printf("errno:%d, error:%s\\n", ret, strerror(ret));
return -1;
}
//等待线程结束,若线程在运行,则阻塞等待
//若线程结束,立即返回
//第一个参数:要等待的线程
//第二个参数:要来获得线程的返回值
pthread_join(thread, NULL);
while (1)
{
printf("this is main...\\n");
sleep(1);
}
return 0;
}
运算结果:
pthread_mutex.c
#include <pthread.h> //pthread_create()
#include <stdio.h>
#include <string.h> //strerror()
#include <errno.h> //errno
#include <unistd.h>
pthread_mutex_t mutex; //互斥量--锁
int g_iData = 0;
void *thread_run(void *arg)
{
while (1)
{
//使用pthread_mutex_lock和pthread_mutex_unlock
//使它们之间的语句合成原子操作
//若其他线程没有释放该互斥量
//则本线程阻塞等待
//pthread_mutex_lock(&mutex);
//pthread_mutex_trylock(&mutex);
++g_iData;
printf("thread:data = %d\\n", g_iData);
pthread_mutex_unlock(&mutex);
}
return NULL;
}
int main(void)
{
//初始化互斥量,NULL表示使用默认属性初始化该互斥量
pthread_mutex_init(&mutex, NULL);
pthread_t thread;
int ret = 0;
ret = pthread_create(&thread, NULL, thread_run, NULL);
if (0 != ret)
{
printf("errno:%d, error:%s\\n", ret, strerror(ret));
return -1;
}
while (1)
{
pthread_mutex_lock(&mutex);
++g_iData;
printf("main:data = %d\\n", g_iData);
pthread_mutex_unlock(&mutex);
}
return 0;
}
运算结果:
pthread_share
#include <pthread.h> //pthread_create()
#include <stdio.h>
#include <string.h> //strerror()
#include <errno.h> //errno
#include <unistd.h>
int g_iData = 999;
void *thread_run(void *arg)
{
//while (1)
{
printf("this is thread_run...iData = %d\\n", g_iData);
g_iData++;
//sleep(1);
}
return NULL;
}
int main(void)
{
pthread_t thread;
int ret = 0;
ret = pthread_create(&thread, NULL, thread_run, NULL);
if (0 != ret)
{
printf("errno:%d, error:%s\\n", ret, strerror(ret));
return -1;
}
sleep(2);
// while (1)
{
printf("this is main...iData = %d\\n", g_iData);
// sleep(1);
}
return 0;
}
运算结果:
read_stu
#include <stdio.h>
#include <unistd.h> //write() read()
#include <errno.h> //errno
#include <string.h> //strerror()
/*open()*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h> //pthread_create
pthread_mutex_t mutex;
#define NAME_LEN 32
typedef struct Student
{
int iId;
char caName[NAME_re LEN];
char cSex;
float fScore;
}Student;
int myOpen(const char *pathname)
{
int fd = -1;
if (NULL != pathname)
{
fd = open(pathname, O_RDONLY | O_CREAT
, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (-1 == fd)
{
printf("open error: %s\\n", strerror(errno));
}
}
return fd;
}
int g_iSign = 0;
void *read_thread(void *arg)
{
int fd = -1;
fd = myOpen("stu.info");
if (-1 != fd)
{
int ret = -1;
Student *pStu = (Student *)arg;
while (1)
{
if (0 == g_iSign)
{
pthread_mutex_lock(&mutex);
memset(pStu, '\\0', sizeof(Student));
ret = read(fd, pStu, sizeof(Student));
if (0 == ret)
{
printf("reached the file end\\n");
pthread_mutex_unlock(&mutex);
g_iSign = 1;
break;
}
else if (-1 == ret)
{
printf("read error:%s\\n", strerror(errno));
pthread_mutex_unlock(&mutex);
g_iSign = 1;
break;
}
pthread_mutex_unlock(&mutex);
g_iSign = 1;
}
}
close(fd);
}
return NULL;
}
void *print_thread(void *arg)
{
Student *pStu = (Student *)arg;
int i = 0;
while (1)
{
if (1 == g_iSign)
{
pthread_mutex_lock(&mutex);
if (0 == pStu->iId)
{
pthread_mutex_unlock(&mutex);
break;
}
printf("id:%d, name:%s, sex:%c, score:%.1f\\n"
, pStu->iId, pStu->caName
, pStu->cSex, pStu->fScore);
pthread_mutex_unlock(&mutex);
g_iSign = 0;
}
}
return NULL;
}
int main(void)
{
pthread_mutex_init(&mutex, NULL);
Student stu;
pthread_t pthr_read;
pthread_t pthr_show;
pthread_create(&pthr_read, NULL, read_thread, &stu);
pthread_create(&pthr_show, NULL, print_thread, &stu);
pthread_join(pthr_read, NULL);
pthread_join(pthr_show, NULL);
return 0;
}
运算结果:
write_stu.c
#include <stdio.h>
#include <unistd.h> //write()
#include <errno.h> //errno
#include <string.h> //strerror()
/*open()*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define NAME_LEN 32
typedef struct Student
{
int iId;
char caName[NAME_LEN];
char cSex;
float fScore;
}Student;
int myOpen(const char *pathname)
{
int fd = -1;
if (NULL != pathname)
{
fd = open(pathname, O_WRONLY | O_CREAT | O_TRUNC
, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (-1 == fd)
{
printf("open error: %s\\n", strerror(errno));
}
}
return fd;
}
int main(void)
{
int fd = -1;
fd = myOpen("stu.info");
if (-1 != fd)
{
Student stu[6] = {{1001, "zhangsan", 'f', 99}
, {1002, "lisi", 'm', 79}
, {1003, "wangwu", 'f', 89}
, {1004, "zhaoliu", 'm', 69}
, {1005, "xiaoqi", 'm', 79}
, {1006, "laoba", 'f', 89}};
int ret = -1;
int i = 0;
for (; i < 6; i++)
{
ret = write(fd, stu+i, sizeof(Student));
if (-1 == ret)
{
printf("write error: %s\\n", strerror(errno));
}
else
{
printf("write %d bytes to file\\n", ret);
}
}
}
return 0;
}
sem_read_stu.c
#include <stdio.h>
#include <unistd.h> //write() read()
#include <errno.h> //errno
#include <string.h> //strerror()
/*open()*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h> //pthread_create
#include <semaphore.h>
pthread_mutex_t mutex;
sem_t read_sem; //整形
sem_t show_sem;
#define NAME_LEN 32
typedef struct Student
{
int iId;
char caName[NAME_LEN];
char cSex;
float fScore;
}Student;
int myOpen(const char *pathname)
{
int fd = -1;
if (NULL != pathname)
{
fd = open(pathname, O_RDONLY | O_CREAT
, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (-1 == fd)
{
printf("open error: %s\\n", strerror(errno));
}
}
return fd;
}
void *read_thread(void *arg)
{
int fd = -1;
fd = myOpen("stu.info");
if (-1 != fd)
{
int ret = -1;
Student *pStu = (Student *)arg;
while (1)
{
//如果read_sem大于0,接着往下执行,并且将该变量减一
//如果read_sem等于0,则阻塞,直到该值大于0
sem_wait(&read_sem);
pthread_mutex_lock(&mutex);
memset(pStu, '\\0', sizeof(Student));
ret = read(fd, pStu, sizeof(Student));
if (0 == ret)
{
printf("reached the file end\\n");
pthread_mutex_unlock(&mutex);
sem_post(&show_sem);
break;
}
else if (-1 == ret)
{
printf("read error:%s\\n", strerror(errno));
pthread_mutex_unlock(&mutex);
sem_post(&show_sem);
break;
}
pthread_mutex_unlock(&mutex);
//将信号量的值加一
sem_post(&show_sem);
}
}
close(fd);
return NULL;
}
void *print_thread(void *arg)
{
Student *pStu = (Student *)arg;
int i = 0;
while (1)
{
{
//如果show_sem大于0,接着往下执行,并且将该变量减一
//如果show_sem等于0,则阻塞,直到该值大于0
sem_wait(&show_sem);
pthread_mutex_lock(&mutex);
if (0 == pStu->iId)
{
pthread_mutex_unlock(&mutex);
sem_post(&read_sem);
break;
}
printf("id:%d, name:%s, sex:%c, score:%.1f\\n"
, pStu->iId, pStu->caName
, pStu->cSex, pStu->fScore);
pthread_mutex_unlock(&mutex);
//将信号量的值加一
sem_post(&read_sem);
}
}
return NULL;
}
int main(void)
{
pthread_mutex_init(&mutex, NULL);
//初始化信号量
sem_init(&read_sem, 0, 1); //将read_sem值置为1
sem_init(&show_sem, 0, 0); //将show_sem值置为0
Student stu;
pthread_t pthr_read;
pthread_t pthr_show;
pthread_create(&pthr_read, NULL, read_thread, &stu);
pthread_create(&pthr_show, NULL, print_thread, &stu);
pthread_join(pthr_read, NULL);
pthread_join(pthr_show, NULL);
return 0;
}
运算结果:
write_stu.c
#include <stdio.h>
#include <unistd.h> //write()
#include <errno.h> //errno
#include <string.h> //strerror()
/*open()*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define NAME_LEN 32
typedef struct Student
{
int iId;
char caName[NAME_LEN];
char cSex;
float fScore;
}Student;
int myOpen(const char *pathname)
{
int fd = -1;
if (NULL != pathname)
{
fd = open(pathname, O_WRONLY | O_CREAT | O_TRUNC
, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (-1 == fd)
{
printf("open error: %s\\n", strerror(errno));
}
}
return fd;
}
int main(void)
{
int fd = -1;
fd = myOpen("stu.info");
if (-1 != fd)
{
Student stu[6] = {{1001, "zhangsan", 'f', 99}
, {1002, "lisi", 'm', 79}
, {1003, "wangwu", 'f', 89}
, {1004, "zhaoliu", 'm', 69}
, {1005, "xiaoqi", 'm', 79}
, {1006, "laoba", 'f', 89}};
int ret = -1;
int i = 0;
for (; i < 6; i++)
{
ret = write(fd, stu+i, sizeof(Student));
if (-1 == ret)
{
printf("write error: %s\\n", strerror(errno));
}
else
{
printf("write %d bytes to file\\n", ret);
}
}
}
return 0;
}
运算结果:
think-eat.c
/*semget()*/
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <string.h> //perror()
#include <unistd.h> //fork()
#include <stdio.h> //printf()
union semun
{
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT,IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO(Linux-specific) */
};
#if 0
int semop(int semid, struct sembuf *sops, unsigned nsops);
参数
semid:信号集的识别码,可通过semget获取。
sops:指向存储信号操作结构的数组指针,信号操作结构的原型如下
struct sembuf
{
unsigned short sem_num; /* semaphore number */
short sem_op; /* semaphore operation */
short sem_flg; /* operation flags */
};
这三个字段的意义分别为:
sem_num:操作信号在信号集中的编号,第一个信号的编号是0。
sem_op:
1, 如果其值为正数,该值会加到现有的信号内含值中。
通常用于释放所控资源的使用权;
2, 如果sem_op的值为负数,而其绝对值又大于信号的现值,
操作将会阻塞,直到信号值大于或等于sem_op的绝对值。
通常用于获取资源的使用权;
3, 如果sem_op的值为0,如果没有设置IPC_NOWAIT,
则调用该操作的进程或者线程将暂时睡眠,直到信号量的值为0; 否则,进程或者线程不会睡眠,函数返回错误EAGAIN。
sem_flg:信号操作标志,可能的选择有两种
1, IPC_NOWAIT //对信号的操作不能满足时,semop()不会阻塞,
并立即返回,同时设定错误信息。
2, SEM_UNDO //程序结束时(不论正常或不正常),
保证信号值会被重设为semop()调用前的值。
这样做的目的在于避免程序在异常情况下结束时
未将锁定的资源解锁,造成该资源永远锁定。
nsops:信号操作结构的数量,恒大于或等于1。
#endif
void getChopsticks(int iNum, int *semfd)
{
int iLeft = iNum;
int iRight = (iNum + 1)%5;
struct sembuf semope[2] = {{iLeft, -1, 0}
, {iRight, -1, 0}};
semop(*semfd, semope, 2);
}
void putChopsticks(int iNum, int *semfd)
{
int iLeft = iNum;
int iRight = (iNum + 1)%5;
struct sembuf semope[2] = {{iLeft, 1, 0}
, {iRight, 1, 0}};
semop(*semfd, semope, 2);
}
void thinkAndEat(int iNum, int *semfd)
{
while (1)
{
printf("%d say: I am thinking...\\n", iNum);
/*拿筷子吃饭*/
getChopsticks(iNum, semfd);
sleep(1);
printf("%d say: I am eatting...\\n", iNum);
/*放下筷子*/
putChopsticks(iNum, semfd);
printf("%d say: I am put chopsticks...\\n", iNum);
sleep(1);
}
}
int main(void)
{
int semfd = -1;
//获得信号量集的标识,若信号量集不存在则创建
semfd = semget(0x1024, 5, IPC_CREAT | 0777);
if (-1 == semfd)
{
perror("semget");
return -1;
}
//对信号集中的信号量赋值
union semun sem;
sem.val = 1;
int i = 0;
for (; i < 5; i++)
{
if (-1 == semctl(semfd, i, SETVAL, sem))
{
perror("semctl");
return -1;
}
}
//创建五个哲学家进程
int num = 0; //表示第几个哲学家
pid_t pid = -1;
for (i = 0; i < 4; i++)
{
pid = fork();
if (pid > 0) //parent
{
num = 4;
}
else if (0 == pid) //child
{
num = i;
break;
}
else if (-1 == pid) //error
{
return -1;
}
}
thinkAndEat(num, &semfd);
return 0;
}
运算结果: