分享条件变量和放大器;进程之间的互斥:互斥是否有锁定之前? [英] Share condition variable & mutex between processes: does mutex have to locked before?
问题描述
我需要一些小的帮助,了解如何使用条件变量用C来解决的练习。这里是一个小例子:
的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&unistd.h中GT;
#包括LT&;&pthreads.h中GT;
#包括LT&;&string.h中GT;
#包括LT&;&errno.h中GT;
#包括LT&; SYS / types.h中>
#包括LT&; SYS / mman.h>
#包括LT&; SYS / stat.h>
#包括LT&;&fcntl.h GT;#定义OKTOWRITE/ oktowrite
#定义MESSAGE/消息
#定义MUTEX/锁INT主(INT ARGC,字符** argv的)
{
pthread_cond_t的*条件;
pthread_mutex_t *互斥;
字符*消息;
INT des_cond,des_msg,des_mutex;
INT模式= S_IRWXU | S_IRWXG; des_mutex =的shm_open(互斥,O_CREAT | O_RDWR | O_TRUNC,模式); 如果(des_mutex℃,)
{
PERROR(失败上的shm_open上des_mutex);
出口(1);
} 如果(ftruncate(des_mutex,sizeof的(pthread_mutex_t))== -1)
{
PERROR(关于ftruncate为sizeof pthread_cond_t的\\ n错误);
出口(-1);
} 互斥量=(pthread_mutex_t *)MMAP(NULL,的sizeof(pthread_mutex_t)
PROT_READ | PROT_WRITE,MAP_SHARED,des_mutex,0); 如果(互斥== MAP_FAILED)
{
PERROR(关于互斥\\ n MMAP错误);
出口(1);
} 调用pthread_mutex_init(互斥,NULL); des_cond =的shm_open(OKTOWRITE,O_CREAT | O_RDWR | O_TRUNC,模式); 如果(des_cond℃,)
{
PERROR(失败上的shm_open上des_cond);
出口(1);
} 如果(ftruncate(des_cond,sizeof的(pthread_cond_t的))== -1)
{
PERROR(关于ftruncate为sizeof pthread_cond_t的\\ n错误);
出口(-1);
} 条件=(pthread_cond_t的*)的mmap(NULL,的sizeof(pthread_cond_t的)
PROT_READ | PROT_WRITE,MAP_SHARED,des_cond,0); 如果(条件== MAP_FAILED)
{
PERROR(关于条件\\ n的mmap错误);
出口(1);
} pthread_cond_init(条件,NULL); 如果(!叉())
{
睡眠(3);
调用pthread_mutex_lock(互斥);
调用pthread_cond_signal(条件);
调用pthread_mutex_unlock(互斥);
的printf(儿子信号\\ n);
出口(0);
}
其他
{
输出(等待状态\\ n); 调用pthread_mutex_lock(互斥);
调用pthread_cond_wait(条件,互斥);
调用pthread_mutex_unlock(互斥); 的printf(由子进程有信号,唤醒\\ n); pthread_mutex_destroy(互斥);
pthread_cond_destroy(条件); shm_unlink(OKTOWRITE);
shm_unlink(消息);
shm_unlink(MUTEX); 返回0;
}
}
的问题是,该方法的父亲不断被锁定,即使经过儿子的信令。一切都在共享内存(使用的shm_open
和 MMAP
),这样的情况应该是这两个过程是相同的。
我是不是可能是通过调用wait或信号之前锁定互斥犯了一个错误?
编辑:
感谢所有谁帮助了我。这里是正确的code与关键部位标明:
的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&unistd.h中GT;
#包括LT&;&pthreads.h中GT;
#包括LT&;&string.h中GT;
#包括LT&;&errno.h中GT;
#包括LT&; SYS / types.h中>
#包括LT&; SYS / mman.h>
#包括LT&; SYS / stat.h>
#包括LT&;&fcntl.h GT;#定义OKTOWRITE/ condwrite
#定义MESSAGE/味精
#定义MUTEX/的mutex_lockINT主(INT ARGC,字符** argv的){pthread_cond_t的*条件;
pthread_mutex_t *互斥;
字符*消息;
INT des_cond,des_msg,des_mutex;
INT模式= S_IRWXU | S_IRWXG;des_mutex =的shm_open(互斥,O_CREAT | O_RDWR | O_TRUNC,模式);如果(des_mutex℃,){
PERROR(失败上的shm_open上des_mutex);
出口(1);
}如果(ftruncate(des_mutex,sizeof的(pthread_mutex_t))== -1){
PERROR(关于ftruncate为sizeof pthread_cond_t的\\ n错误);
出口(-1);
}互斥量=(pthread_mutex_t *)MMAP(NULL,的sizeof(pthread_mutex_t)
PROT_READ | PROT_WRITE,MAP_SHARED,des_mutex,0);如果(互斥== MAP_FAILED){
PERROR(关于互斥\\ n MMAP错误);
出口(1);
}des_cond =的shm_open(OKTOWRITE,O_CREAT | O_RDWR | O_TRUNC,模式);如果(des_cond℃,){
PERROR(失败上的shm_open上des_cond);
出口(1);
}如果(ftruncate(des_cond,sizeof的(pthread_cond_t的))== -1){
PERROR(关于ftruncate为sizeof pthread_cond_t的\\ n错误);
出口(-1);
}条件=(pthread_cond_t的*)的mmap(NULL,的sizeof(pthread_cond_t的)
PROT_READ | PROT_WRITE,MAP_SHARED,des_cond,0);如果(条件== MAP_FAILED){
PERROR(关于条件\\ n的mmap错误);
出口(1);
}
/* 开始了 */
/ *************** / / *设置互斥进程间共享* /
pthread_mutexattr_t mutexAttr;
pthread_mutexattr_setpshared(安培; mutexAttr,PTHREAD_PROCESS_SHARED);
调用pthread_mutex_init(互斥体,和放大器; mutexAttr);进程间共享/ *设置条件* /
pthread_condattr_t condAttr;
pthread_condattr_setpshared(安培; condAttr,PTHREAD_PROCESS_SHARED);
pthread_cond_init(条件,和放大器; condAttr); / ********* /如果(!叉()){ 睡眠(10); 调用pthread_mutex_lock(互斥);
调用pthread_cond_signal(条件);
的printf(儿子信号\\ n);
调用pthread_mutex_unlock(互斥);
出口(0);
}其他{ 的printf(父亲等待条件\\ n); 调用pthread_mutex_lock(互斥);
调用pthread_cond_wait(条件,互斥);
调用pthread_mutex_unlock(互斥); 的printf(由子进程有信号,唤醒!!!!!!!! \\ n); pthread_condattr_destroy(安培; condAttr);
pthread_mutexattr_destroy(安培; mutexAttr);
pthread_mutex_destroy(互斥);
pthread_cond_destroy(条件); shm_unlink(OKTOWRITE);
shm_unlink(消息);
shm_unlink(MUTEX);}返回0;}
要成为一个互斥体需要通过正确初始化属性初始化相应的进程间共享:<一href=\"http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutexattr_setpshared.html\">http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutexattr_setpshared.html
的#include&LT; pthreads.h中&GT;...pthread_mutex_t * pmutex = NULL;
pthread_mutexattr_t attrmutex;/ *初始化属性互斥。 * /
pthread_mutexattr_init(安培; attrmutex);
pthread_mutexattr_setpshared(安培; attrmutex,PTHREAD_PROCESS_SHARED);/ *分配内存来这里pmutex。 * // *初始化互斥。 * /
调用pthread_mutex_init(pmutex,&安培; attrmutex);/ *使用互斥。 * //* 清理。 * /
pthread_mutex_destroy(pmutex);
pthread_mutexattr_destroy(安培; attrmutex);
(左检查出错误这个例子的可读性的缘故)
这同样适用于其中应进程之间共享的状态变量:<一href=\"http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_condattr_setpshared.html\">http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_condattr_setpshared.html
的#include&LT; pthreads.h中&GT;...pthread_cond_t的* pcond = NULL;
pthread_condattr_t attrcond;/ *初始化属性的条件。 * /
pthread_condattr_init(安培; attrcond);
pthread_condattr_setpshared(安培; attrcond,PTHREAD_PROCESS_SHARED);/ *分配内存来这里pcond。 * // *初始化状态。 * /
pthread_cond_init(pcond,&安培; attrcond);/ *使用的条件。 * //* 清理。 * /
pthread_cond_destroy(pcond);
pthread_condattr_destroy(安培; attrcond);
(左检查出错误这个例子的可读性的缘故)
另见这样的回答: http://stackoverflow.com/a/2390670/694576
I need to some little help to understand how to use condition variables in C to resolve an exercise. Here is a little example:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#define OKTOWRITE "/oktowrite"
#define MESSAGE "/message"
#define MUTEX "/lock"
int main(int argc, char** argv)
{
pthread_cond_t* condition;
pthread_mutex_t *mutex;
char* message;
int des_cond, des_msg, des_mutex;
int mode = S_IRWXU | S_IRWXG;
des_mutex = shm_open(MUTEX, O_CREAT | O_RDWR | O_TRUNC, mode);
if (des_mutex < 0)
{
perror("failure on shm_open on des_mutex");
exit(1);
}
if (ftruncate(des_mutex, sizeof(pthread_mutex_t)) == -1)
{
perror("Error on ftruncate to sizeof pthread_cond_t\n");
exit(-1);
}
mutex = (pthread_mutex_t*) mmap(NULL, sizeof(pthread_mutex_t),
PROT_READ | PROT_WRITE, MAP_SHARED, des_mutex, 0);
if (mutex == MAP_FAILED )
{
perror("Error on mmap on mutex\n");
exit(1);
}
pthread_mutex_init(mutex, NULL );
des_cond = shm_open(OKTOWRITE, O_CREAT | O_RDWR | O_TRUNC, mode);
if (des_cond < 0)
{
perror("failure on shm_open on des_cond");
exit(1);
}
if (ftruncate(des_cond, sizeof(pthread_cond_t)) == -1)
{
perror("Error on ftruncate to sizeof pthread_cond_t\n");
exit(-1);
}
condition = (pthread_cond_t*) mmap(NULL, sizeof(pthread_cond_t),
PROT_READ | PROT_WRITE, MAP_SHARED, des_cond, 0);
if (condition == MAP_FAILED )
{
perror("Error on mmap on condition\n");
exit(1);
}
pthread_cond_init(condition, NULL );
if (!fork())
{
sleep(3);
pthread_mutex_lock(mutex);
pthread_cond_signal(condition);
pthread_mutex_unlock(mutex);
printf("son signaled\n");
exit(0);
}
else
{
printf("wait on condition\n");
pthread_mutex_lock(mutex);
pthread_cond_wait(condition, mutex);
pthread_mutex_unlock(mutex);
printf("Signaled by son process, wake up\n");
pthread_mutex_destroy(mutex);
pthread_cond_destroy(condition);
shm_unlink(OKTOWRITE);
shm_unlink(MESSAGE);
shm_unlink(MUTEX);
return 0;
}
}
The problem is that the father of the process keeps on being locked, even after son's signaling. Everything is in shared memory (using shm_open
and mmap
) so the condition should be the same for both the processes.
Am I maybe making a mistake by locking the mutex before calling wait or signal?
EDIT: Thanks to all who helped me. Here's the right code with the CRITICAL parts marked:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#define OKTOWRITE "/condwrite"
#define MESSAGE "/msg"
#define MUTEX "/mutex_lock"
int main(int argc, char** argv) {
pthread_cond_t* condition;
pthread_mutex_t* mutex;
char* message;
int des_cond, des_msg, des_mutex;
int mode = S_IRWXU | S_IRWXG;
des_mutex = shm_open(MUTEX, O_CREAT | O_RDWR | O_TRUNC, mode);
if (des_mutex < 0) {
perror("failure on shm_open on des_mutex");
exit(1);
}
if (ftruncate(des_mutex, sizeof(pthread_mutex_t)) == -1) {
perror("Error on ftruncate to sizeof pthread_cond_t\n");
exit(-1);
}
mutex = (pthread_mutex_t*) mmap(NULL, sizeof(pthread_mutex_t),
PROT_READ | PROT_WRITE, MAP_SHARED, des_mutex, 0);
if (mutex == MAP_FAILED ) {
perror("Error on mmap on mutex\n");
exit(1);
}
des_cond = shm_open(OKTOWRITE, O_CREAT | O_RDWR | O_TRUNC, mode);
if (des_cond < 0) {
perror("failure on shm_open on des_cond");
exit(1);
}
if (ftruncate(des_cond, sizeof(pthread_cond_t)) == -1) {
perror("Error on ftruncate to sizeof pthread_cond_t\n");
exit(-1);
}
condition = (pthread_cond_t*) mmap(NULL, sizeof(pthread_cond_t),
PROT_READ | PROT_WRITE, MAP_SHARED, des_cond, 0);
if (condition == MAP_FAILED ) {
perror("Error on mmap on condition\n");
exit(1);
}
/* HERE WE GO */
/**************************************/
/* set mutex shared between processes */
pthread_mutexattr_t mutexAttr;
pthread_mutexattr_setpshared(&mutexAttr, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(mutex, &mutexAttr);
/* set condition shared between processes */
pthread_condattr_t condAttr;
pthread_condattr_setpshared(&condAttr, PTHREAD_PROCESS_SHARED);
pthread_cond_init(condition, &condAttr);
/*************************************/
if (!fork()) {
sleep(10);
pthread_mutex_lock(mutex);
pthread_cond_signal(condition);
printf("son signaled\n");
pthread_mutex_unlock(mutex);
exit(0);
}
else {
printf("father waits on condition\n");
pthread_mutex_lock(mutex);
pthread_cond_wait(condition, mutex);
pthread_mutex_unlock(mutex);
printf("Signaled by son process, wake up!!!!!!!!\n");
pthread_condattr_destroy(&condAttr);
pthread_mutexattr_destroy(&mutexAttr);
pthread_mutex_destroy(mutex);
pthread_cond_destroy(condition);
shm_unlink(OKTOWRITE);
shm_unlink(MESSAGE);
shm_unlink(MUTEX);
}
return 0;
}
To be sharable between processes a mutex needs to initialised accordingly via a properly initialised attribute: http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutexattr_setpshared.html
#include <pthread.h>
...
pthread_mutex_t * pmutex = NULL;
pthread_mutexattr_t attrmutex;
/* Initialise attribute to mutex. */
pthread_mutexattr_init(&attrmutex);
pthread_mutexattr_setpshared(&attrmutex, PTHREAD_PROCESS_SHARED);
/* Allocate memory to pmutex here. */
/* Initialise mutex. */
pthread_mutex_init(pmutex, &attrmutex);
/* Use the mutex. */
/* Clean up. */
pthread_mutex_destroy(pmutex);
pthread_mutexattr_destroy(&attrmutex);
(error checking left out for the sake of this example's readability)
The same applies to a condition variable which should be shared between processes: http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_condattr_setpshared.html
#include <pthread.h>
...
pthread_cond_t * pcond = NULL;
pthread_condattr_t attrcond;
/* Initialise attribute to condition. */
pthread_condattr_init(&attrcond);
pthread_condattr_setpshared(&attrcond, PTHREAD_PROCESS_SHARED);
/* Allocate memory to pcond here. */
/* Initialise condition. */
pthread_cond_init(pcond, &attrcond);
/* Use the condition. */
/* Clean up. */
pthread_cond_destroy(pcond);
pthread_condattr_destroy(&attrcond);
(error checking left out for the sake of this example's readability)
Also see this answer: http://stackoverflow.com/a/2390670/694576
这篇关于分享条件变量和放大器;进程之间的互斥:互斥是否有锁定之前?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!